Loading CHANGES +3 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,9 @@ Changes between 1.0.0 and 1.1.0 [xx XXX xxxx] *) Initial CMAC implementation. WARNING: EXPERIMENTAL, API MAY CHANGE. [Steve Henson] *) Experiemental regnegotiation in s_server -www mode. If the client browses /reneg connection is renegotiated. If /renegcert it is renegotiated requesting a certificate. Loading Makefile.org +1 −1 Original line number Diff line number Diff line Loading @@ -121,7 +121,7 @@ SDIRS= \ bn ec rsa dsa ecdsa dh ecdh dso engine \ buffer bio stack lhash rand err \ evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \ cms pqueue ts jpake store cms pqueue ts jpake store cmac # keep in mind that the above list is adjusted by ./Configure # according to no-xxx arguments... Loading crypto/cmac/Makefile 0 → 100644 +76 −0 Original line number Diff line number Diff line # # OpenSSL/crypto/cmac/Makefile # DIR= cmac TOP= ../.. CC= cc INCLUDES= CFLAG=-g MAKEFILE= Makefile AR= ar r CFLAGS= $(INCLUDES) $(CFLAG) GENERAL=Makefile TEST= APPS= LIB=$(TOP)/libcrypto.a LIBSRC=cmac.c LIBOBJ=cmac.o SRC= $(LIBSRC) EXHEADER= cmac.h HEADER= $(EXHEADER) ALL= $(GENERAL) $(SRC) $(HEADER) top: (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) all: lib lib: $(LIBOBJ) $(AR) $(LIB) $(LIBOBJ) $(RANLIB) $(LIB) || echo Never mind. @touch lib files: $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO links: @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) install: @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile... @headerlist="$(EXHEADER)"; for i in $$headerlist ; \ do \ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ done; tags: ctags $(SRC) tests: lint: lint -DLINT $(INCLUDES) $(SRC)>fluff depend: @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile... $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC) dclean: $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new mv -f Makefile.new $(MAKEFILE) clean: rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff # DO NOT DELETE THIS LINE -- make depend depends on it. crypto/cmac/cmac.c 0 → 100644 +232 −0 Original line number Diff line number Diff line /* crypto/cmac/cmac.c */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. */ /* ==================================================================== * Copyright (c) 2010 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "cryptlib.h" #include <openssl/cmac.h> struct CMAC_CTX_st { /* Cipher context to use */ EVP_CIPHER_CTX cctx; /* Keys k1 and k2 */ unsigned char k1[EVP_MAX_BLOCK_LENGTH]; unsigned char k2[EVP_MAX_BLOCK_LENGTH]; /* Temporary block */ unsigned char tbl[EVP_MAX_BLOCK_LENGTH]; /* Last (possibly partial) block */ unsigned char last_block[EVP_MAX_BLOCK_LENGTH]; /* Number of bytes in last block: -1 means context not initialised */ int nlast_block; }; /* Make temporary keys K1 and K2 */ static void make_kn(unsigned char *k1, unsigned char *l, int bl) { int i; /* Shift block to left, including carry */ for (i = 0; i < bl; i++) { k1[i] = l[i] << 1; if (i < bl - 1 && l[i + 1] & 0x80) k1[i] |= 1; } /* If MSB set fixup with R */ if (l[0] & 0x80) k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b; } CMAC_CTX *CMAC_CTX_new(void) { CMAC_CTX *ctx; ctx = OPENSSL_malloc(sizeof(CMAC_CTX)); if (!ctx) return NULL; EVP_CIPHER_CTX_init(&ctx->cctx); ctx->nlast_block = -1; return ctx; } void CMAC_CTX_cleanup(CMAC_CTX *ctx) { EVP_CIPHER_CTX_cleanup(&ctx->cctx); OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH); OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH); OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH); OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH); ctx->nlast_block = -1; } EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx) { return &ctx->cctx; } void CMAC_CTX_free(CMAC_CTX *ctx) { CMAC_CTX_cleanup(ctx); OPENSSL_free(ctx); } int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, const EVP_CIPHER *cipher, ENGINE *impl) { static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH]; /* All zeros means restart */ if (!key && !cipher && !impl && keylen == 0) { /* Not initialised */ if (ctx->last_block == -1) return 0; if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) return 0; return 0; } /* Initialiase context */ if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL)) return 0; /* Non-NULL key means initialisation complete */ if (key) { int bl; if (!EVP_CIPHER_CTX_cipher(&ctx->cctx)) return 0; if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen)) return 0; if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv)) return 0; bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl)) return 0; make_kn(ctx->k1, ctx->tbl, bl); make_kn(ctx->k2, ctx->k1, bl); OPENSSL_cleanse(ctx->tbl, bl); /* Reset context again ready for first data block */ if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) return 0; ctx->nlast_block = 0; } return 1; } int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) { const unsigned char *data = in; size_t bl; if (ctx->nlast_block == -1) return 0; if (dlen == 0) return 1; bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); /* Copy into partial block if we need to */ if (ctx->nlast_block > 0) { size_t nleft; nleft = bl - ctx->nlast_block; if (dlen < nleft) nleft = dlen; memcpy(ctx->last_block + ctx->nlast_block, data, nleft); dlen -= nleft; ctx->nlast_block += nleft; /* If no more to process return */ if (dlen == 0) return 1; data += nleft; /* Else not final block so encrypt it */ if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block,bl)) return 0; } /* Encrypt all but one of the complete blocks left */ while(dlen > bl) { if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl)) return 0; dlen -= bl; data += bl; } /* Copy any data left to last block buffer */ memcpy(ctx->last_block, data, dlen); ctx->nlast_block = dlen; return 1; } size_t CMAC_Final(CMAC_CTX *ctx, unsigned char *out) { int i, bl, lb; if (ctx->nlast_block == -1) return 0; bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); lb = ctx->nlast_block; /* Is last block complete? */ if (lb == bl) { for (i = 0; i < bl; i++) ctx->last_block[i] ^= ctx->k1[i]; } else { ctx->last_block[lb] = 0x80; if (bl - lb > 1) memset(ctx->last_block + lb + 1, 0, bl - lb - 1); for (i = 0; i < bl; i++) ctx->last_block[i] ^= ctx->k2[i]; } if (!EVP_Cipher(&ctx->cctx, out, ctx->last_block, bl)) return 0; return bl; } crypto/cmac/cmac.h 0 → 100644 +80 −0 Original line number Diff line number Diff line /* crypto/cmac/cmac.h */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. */ /* ==================================================================== * Copyright (c) 2010 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== */ #ifndef HEADER_CMAC_H #define HEADER_CMAC_H #ifdef __cplusplus extern "C" { #endif #include <openssl/evp.h> /* Opaque */ typedef struct CMAC_CTX_st CMAC_CTX; CMAC_CTX *CMAC_CTX_new(void); void CMAC_CTX_cleanup(CMAC_CTX *ctx); void CMAC_CTX_free(CMAC_CTX *ctx); EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx); int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, const EVP_CIPHER *cipher, ENGINE *impl); int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen); int CMAC_Final(CMAC_CTX *ctx, unsigned char *out); #ifdef __cplusplus } #endif #endif Loading
CHANGES +3 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,9 @@ Changes between 1.0.0 and 1.1.0 [xx XXX xxxx] *) Initial CMAC implementation. WARNING: EXPERIMENTAL, API MAY CHANGE. [Steve Henson] *) Experiemental regnegotiation in s_server -www mode. If the client browses /reneg connection is renegotiated. If /renegcert it is renegotiated requesting a certificate. Loading
Makefile.org +1 −1 Original line number Diff line number Diff line Loading @@ -121,7 +121,7 @@ SDIRS= \ bn ec rsa dsa ecdsa dh ecdh dso engine \ buffer bio stack lhash rand err \ evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \ cms pqueue ts jpake store cms pqueue ts jpake store cmac # keep in mind that the above list is adjusted by ./Configure # according to no-xxx arguments... Loading
crypto/cmac/Makefile 0 → 100644 +76 −0 Original line number Diff line number Diff line # # OpenSSL/crypto/cmac/Makefile # DIR= cmac TOP= ../.. CC= cc INCLUDES= CFLAG=-g MAKEFILE= Makefile AR= ar r CFLAGS= $(INCLUDES) $(CFLAG) GENERAL=Makefile TEST= APPS= LIB=$(TOP)/libcrypto.a LIBSRC=cmac.c LIBOBJ=cmac.o SRC= $(LIBSRC) EXHEADER= cmac.h HEADER= $(EXHEADER) ALL= $(GENERAL) $(SRC) $(HEADER) top: (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) all: lib lib: $(LIBOBJ) $(AR) $(LIB) $(LIBOBJ) $(RANLIB) $(LIB) || echo Never mind. @touch lib files: $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO links: @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) install: @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile... @headerlist="$(EXHEADER)"; for i in $$headerlist ; \ do \ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ done; tags: ctags $(SRC) tests: lint: lint -DLINT $(INCLUDES) $(SRC)>fluff depend: @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile... $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC) dclean: $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new mv -f Makefile.new $(MAKEFILE) clean: rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff # DO NOT DELETE THIS LINE -- make depend depends on it.
crypto/cmac/cmac.c 0 → 100644 +232 −0 Original line number Diff line number Diff line /* crypto/cmac/cmac.c */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. */ /* ==================================================================== * Copyright (c) 2010 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "cryptlib.h" #include <openssl/cmac.h> struct CMAC_CTX_st { /* Cipher context to use */ EVP_CIPHER_CTX cctx; /* Keys k1 and k2 */ unsigned char k1[EVP_MAX_BLOCK_LENGTH]; unsigned char k2[EVP_MAX_BLOCK_LENGTH]; /* Temporary block */ unsigned char tbl[EVP_MAX_BLOCK_LENGTH]; /* Last (possibly partial) block */ unsigned char last_block[EVP_MAX_BLOCK_LENGTH]; /* Number of bytes in last block: -1 means context not initialised */ int nlast_block; }; /* Make temporary keys K1 and K2 */ static void make_kn(unsigned char *k1, unsigned char *l, int bl) { int i; /* Shift block to left, including carry */ for (i = 0; i < bl; i++) { k1[i] = l[i] << 1; if (i < bl - 1 && l[i + 1] & 0x80) k1[i] |= 1; } /* If MSB set fixup with R */ if (l[0] & 0x80) k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b; } CMAC_CTX *CMAC_CTX_new(void) { CMAC_CTX *ctx; ctx = OPENSSL_malloc(sizeof(CMAC_CTX)); if (!ctx) return NULL; EVP_CIPHER_CTX_init(&ctx->cctx); ctx->nlast_block = -1; return ctx; } void CMAC_CTX_cleanup(CMAC_CTX *ctx) { EVP_CIPHER_CTX_cleanup(&ctx->cctx); OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH); OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH); OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH); OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH); ctx->nlast_block = -1; } EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx) { return &ctx->cctx; } void CMAC_CTX_free(CMAC_CTX *ctx) { CMAC_CTX_cleanup(ctx); OPENSSL_free(ctx); } int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, const EVP_CIPHER *cipher, ENGINE *impl) { static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH]; /* All zeros means restart */ if (!key && !cipher && !impl && keylen == 0) { /* Not initialised */ if (ctx->last_block == -1) return 0; if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) return 0; return 0; } /* Initialiase context */ if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL)) return 0; /* Non-NULL key means initialisation complete */ if (key) { int bl; if (!EVP_CIPHER_CTX_cipher(&ctx->cctx)) return 0; if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen)) return 0; if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv)) return 0; bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl)) return 0; make_kn(ctx->k1, ctx->tbl, bl); make_kn(ctx->k2, ctx->k1, bl); OPENSSL_cleanse(ctx->tbl, bl); /* Reset context again ready for first data block */ if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) return 0; ctx->nlast_block = 0; } return 1; } int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) { const unsigned char *data = in; size_t bl; if (ctx->nlast_block == -1) return 0; if (dlen == 0) return 1; bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); /* Copy into partial block if we need to */ if (ctx->nlast_block > 0) { size_t nleft; nleft = bl - ctx->nlast_block; if (dlen < nleft) nleft = dlen; memcpy(ctx->last_block + ctx->nlast_block, data, nleft); dlen -= nleft; ctx->nlast_block += nleft; /* If no more to process return */ if (dlen == 0) return 1; data += nleft; /* Else not final block so encrypt it */ if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block,bl)) return 0; } /* Encrypt all but one of the complete blocks left */ while(dlen > bl) { if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl)) return 0; dlen -= bl; data += bl; } /* Copy any data left to last block buffer */ memcpy(ctx->last_block, data, dlen); ctx->nlast_block = dlen; return 1; } size_t CMAC_Final(CMAC_CTX *ctx, unsigned char *out) { int i, bl, lb; if (ctx->nlast_block == -1) return 0; bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); lb = ctx->nlast_block; /* Is last block complete? */ if (lb == bl) { for (i = 0; i < bl; i++) ctx->last_block[i] ^= ctx->k1[i]; } else { ctx->last_block[lb] = 0x80; if (bl - lb > 1) memset(ctx->last_block + lb + 1, 0, bl - lb - 1); for (i = 0; i < bl; i++) ctx->last_block[i] ^= ctx->k2[i]; } if (!EVP_Cipher(&ctx->cctx, out, ctx->last_block, bl)) return 0; return bl; }
crypto/cmac/cmac.h 0 → 100644 +80 −0 Original line number Diff line number Diff line /* crypto/cmac/cmac.h */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. */ /* ==================================================================== * Copyright (c) 2010 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== */ #ifndef HEADER_CMAC_H #define HEADER_CMAC_H #ifdef __cplusplus extern "C" { #endif #include <openssl/evp.h> /* Opaque */ typedef struct CMAC_CTX_st CMAC_CTX; CMAC_CTX *CMAC_CTX_new(void); void CMAC_CTX_cleanup(CMAC_CTX *ctx); void CMAC_CTX_free(CMAC_CTX *ctx); EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx); int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, const EVP_CIPHER *cipher, ENGINE *impl); int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen); int CMAC_Final(CMAC_CTX *ctx, unsigned char *out); #ifdef __cplusplus } #endif #endif