diff options
Diffstat (limited to 'Cryptlib/OpenSSL/crypto/modes')
-rw-r--r-- | Cryptlib/OpenSSL/crypto/modes/cbc128.c | 64 | ||||
-rw-r--r-- | Cryptlib/OpenSSL/crypto/modes/ccm128.c | 59 | ||||
-rw-r--r-- | Cryptlib/OpenSSL/crypto/modes/cfb128.c | 70 | ||||
-rw-r--r-- | Cryptlib/OpenSSL/crypto/modes/ctr128.c | 72 | ||||
-rw-r--r-- | Cryptlib/OpenSSL/crypto/modes/cts128.c | 33 | ||||
-rw-r--r-- | Cryptlib/OpenSSL/crypto/modes/gcm128.c | 269 | ||||
-rw-r--r-- | Cryptlib/OpenSSL/crypto/modes/modes_lcl.h | 50 | ||||
-rw-r--r-- | Cryptlib/OpenSSL/crypto/modes/ocb128.c | 568 | ||||
-rw-r--r-- | Cryptlib/OpenSSL/crypto/modes/ofb128.c | 62 | ||||
-rw-r--r-- | Cryptlib/OpenSSL/crypto/modes/wrap128.c | 311 | ||||
-rw-r--r-- | Cryptlib/OpenSSL/crypto/modes/xts128.c | 59 |
11 files changed, 1011 insertions, 606 deletions
diff --git a/Cryptlib/OpenSSL/crypto/modes/cbc128.c b/Cryptlib/OpenSSL/crypto/modes/cbc128.c index c13caea5..4c9bc85e 100644 --- a/Cryptlib/OpenSSL/crypto/modes/cbc128.c +++ b/Cryptlib/OpenSSL/crypto/modes/cbc128.c @@ -1,64 +1,16 @@ -/* ==================================================================== - * Copyright (c) 2008 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 - * openssl-core@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. - * ==================================================================== +/* + * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #include <openssl/crypto.h> #include "modes_lcl.h" #include <string.h> -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include <assert.h> - #if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC) # define STRICT_ALIGNMENT 0 #endif @@ -70,8 +22,6 @@ void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, size_t n; const unsigned char *iv = ivec; - assert(in && out && key && ivec); - #if !defined(OPENSSL_SMALL_FOOTPRINT) if (STRICT_ALIGNMENT && ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { @@ -123,8 +73,6 @@ void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, unsigned char c[16]; } tmp; - assert(in && out && key && ivec); - #if !defined(OPENSSL_SMALL_FOOTPRINT) if (in != out) { const unsigned char *iv = ivec; diff --git a/Cryptlib/OpenSSL/crypto/modes/ccm128.c b/Cryptlib/OpenSSL/crypto/modes/ccm128.c index c1ded0f9..85ce84f1 100644 --- a/Cryptlib/OpenSSL/crypto/modes/ccm128.c +++ b/Cryptlib/OpenSSL/crypto/modes/ccm128.c @@ -1,63 +1,16 @@ -/* ==================================================================== - * Copyright (c) 2011 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 - * openssl-core@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/)" +/* + * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. * - * 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. - * ==================================================================== + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #include <openssl/crypto.h> #include "modes_lcl.h" #include <string.h> -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include <assert.h> - /* * First you setup M and L parameters and pass the key schedule. This is * called once per session setup... diff --git a/Cryptlib/OpenSSL/crypto/modes/cfb128.c b/Cryptlib/OpenSSL/crypto/modes/cfb128.c index d4ecbd08..e439567f 100644 --- a/Cryptlib/OpenSSL/crypto/modes/cfb128.c +++ b/Cryptlib/OpenSSL/crypto/modes/cfb128.c @@ -1,64 +1,16 @@ -/* ==================================================================== - * Copyright (c) 2008 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 - * openssl-core@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. - * ==================================================================== +/* + * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #include <openssl/crypto.h> #include "modes_lcl.h" #include <string.h> -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include <assert.h> - /* * The input and output encrypted as though 128bit cfb mode is being used. * The extra state information to record how much of the 128bit block we have @@ -72,8 +24,6 @@ void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, unsigned int n; size_t l = 0; - assert(in && out && key && ivec && num); - n = *num; if (enc) { @@ -190,7 +140,7 @@ static void cfbr_encrypt_block(const unsigned char *in, unsigned char *out, block128_f block) { int n, rem, num; - unsigned char ovec[16 * 2 + 1]; /* +1 because we dererefence (but don't + unsigned char ovec[16 * 2 + 1]; /* +1 because we dereference (but don't * use) one byte off the end */ if (nbits <= 0 || nbits > 128) @@ -228,9 +178,6 @@ void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, size_t n; unsigned char c[1], d[1]; - assert(in && out && key && ivec && num); - assert(*num == 0); - for (n = 0; n < bits; ++n) { c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; cfbr_encrypt_block(c, d, 1, key, ivec, enc, block); @@ -246,9 +193,6 @@ void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, { size_t n; - assert(in && out && key && ivec && num); - assert(*num == 0); - for (n = 0; n < length; ++n) cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block); } diff --git a/Cryptlib/OpenSSL/crypto/modes/ctr128.c b/Cryptlib/OpenSSL/crypto/modes/ctr128.c index bcafd6b6..03920b44 100644 --- a/Cryptlib/OpenSSL/crypto/modes/ctr128.c +++ b/Cryptlib/OpenSSL/crypto/modes/ctr128.c @@ -1,64 +1,16 @@ -/* ==================================================================== - * Copyright (c) 2008 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 - * openssl-core@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. - * ==================================================================== +/* + * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #include <openssl/crypto.h> #include "modes_lcl.h" #include <string.h> -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include <assert.h> - /* * NOTE: the IV/counter CTR mode is big-endian. The code itself is * endian-neutral. @@ -100,7 +52,7 @@ static void ctr128_inc_aligned(unsigned char *counter) --n; d = data[n] += c; /* did addition carry? */ - c = ((d - c) ^ d) >> (sizeof(size_t) * 8 - 1); + c = ((d - c) & ~d) >> (sizeof(size_t) * 8 - 1); } while (n); } #endif @@ -113,7 +65,7 @@ static void ctr128_inc_aligned(unsigned char *counter) * before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes * that the counter is in the x lower bits of the IV (ivec), and that the * application has full control over overflow and the rest of the IV. This - * implementation takes NO responsability for checking that the counter + * implementation takes NO responsibility for checking that the counter * doesn't overflow into the rest of the IV when incremented. */ void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, @@ -125,9 +77,6 @@ void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, unsigned int n; size_t l = 0; - assert(in && out && key && ecount_buf && num); - assert(*num < 16); - n = *num; #if !defined(OPENSSL_SMALL_FOOTPRINT) @@ -203,9 +152,6 @@ void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, { unsigned int n, ctr32; - assert(in && out && key && ecount_buf && num); - assert(*num < 16); - n = *num; while (n && len) { @@ -238,7 +184,7 @@ void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, (*func) (in, out, blocks, key, ivec); /* (*ctr) does not update ivec, caller does: */ PUTU32(ivec + 12, ctr32); - /* ... overflow was detected, propogate carry. */ + /* ... overflow was detected, propagate carry. */ if (ctr32 == 0) ctr96_inc(ivec); blocks *= 16; diff --git a/Cryptlib/OpenSSL/crypto/modes/cts128.c b/Cryptlib/OpenSSL/crypto/modes/cts128.c index 137be595..77ec994b 100644 --- a/Cryptlib/OpenSSL/crypto/modes/cts128.c +++ b/Cryptlib/OpenSSL/crypto/modes/cts128.c @@ -1,21 +1,16 @@ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. +/* + * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Rights for redistribution and usage in source and binary - * forms are granted according to the OpenSSL license. + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #include <openssl/crypto.h> #include "modes_lcl.h" #include <string.h> -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include <assert.h> - /* * Trouble with Ciphertext Stealing, CTS, mode is that there is no * common official specification, but couple of cipher/application @@ -36,8 +31,6 @@ size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, { size_t residue, n; - assert(in && out && key && ivec); - if (len <= 16) return 0; @@ -68,8 +61,6 @@ size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, { size_t residue, n; - assert(in && out && key && ivec); - if (len < 16) return 0; @@ -103,8 +94,6 @@ size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, unsigned char c[16]; } tmp; - assert(in && out && key && ivec); - if (len <= 16) return 0; @@ -141,8 +130,6 @@ size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out, unsigned char c[16]; } tmp; - assert(in && out && key && ivec); - if (len < 16) return 0; @@ -179,8 +166,6 @@ size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char c[32]; } tmp; - assert(in && out && key && ivec); - if (len <= 16) return 0; @@ -224,8 +209,6 @@ size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, unsigned char c[32]; } tmp; - assert(in && out && key && ivec); - if (len < 16) return 0; @@ -272,8 +255,6 @@ size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, unsigned char c[32]; } tmp; - assert(in && out && key && ivec); - if (len <= 16) return 0; @@ -314,8 +295,6 @@ size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out, unsigned char c[32]; } tmp; - assert(in && out && key && ivec); - if (len < 16) return 0; diff --git a/Cryptlib/OpenSSL/crypto/modes/gcm128.c b/Cryptlib/OpenSSL/crypto/modes/gcm128.c index e299131c..df9f6547 100644 --- a/Cryptlib/OpenSSL/crypto/modes/gcm128.c +++ b/Cryptlib/OpenSSL/crypto/modes/gcm128.c @@ -1,65 +1,16 @@ -/* ==================================================================== - * 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 - * openssl-core@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/)" +/* + * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved. * - * 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. - * ==================================================================== + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ -#define OPENSSL_FIPSAPI - #include <openssl/crypto.h> #include "modes_lcl.h" #include <string.h> -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include <assert.h> - #if defined(BSWAP4) && defined(STRICT_ALIGNMENT) /* redefine, because alignment is ensured */ # undef GETU32 @@ -150,9 +101,7 @@ static void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256]) const union { long one; char little; - } is_endian = { - 1 - }; + } is_endian = { 1 }; static const size_t rem_8bit[256] = { PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246), PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E), @@ -321,9 +270,7 @@ static void gcm_init_4bit(u128 Htable[16], u64 H[2]) const union { long one; char little; - } is_endian = { - 1 - }; + } is_endian = { 1 }; if (is_endian.little) for (j = 0; j < 16; ++j) { @@ -356,9 +303,7 @@ static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]) const union { long one; char little; - } is_endian = { - 1 - }; + } is_endian = { 1 }; nlo = ((const u8 *)Xi)[15]; nhi = nlo >> 4; @@ -437,9 +382,7 @@ static void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], const union { long one; char little; - } is_endian = { - 1 - }; + } is_endian = { 1 }; # if 1 do { @@ -629,9 +572,7 @@ static void gcm_gmult_1bit(u64 Xi[2], const u64 H[2]) const union { long one; char little; - } is_endian = { - 1 - }; + } is_endian = { 1 }; V.hi = H[0]; /* H is in host byte order, no byte swapping */ V.lo = H[1]; @@ -774,9 +715,7 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) const union { long one; char little; - } is_endian = { - 1 - }; + } is_endian = { 1 }; memset(ctx, 0, sizeof(*ctx)); ctx->block = block; @@ -801,6 +740,11 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) #if TABLE_BITS==8 gcm_init_8bit(ctx->Htable, ctx->H.u); #elif TABLE_BITS==4 +# if defined(GHASH) +# define CTX__GHASH(f) (ctx->ghash = (f)) +# else +# define CTX__GHASH(f) (ctx->ghash = NULL) +# endif # if defined(GHASH_ASM_X86_OR_64) # if !defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2) if (OPENSSL_ia32cap_P[0] & (1 << 24) && /* check FXSR bit */ @@ -808,11 +752,11 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) if (((OPENSSL_ia32cap_P[1] >> 22) & 0x41) == 0x41) { /* AVX+MOVBE */ gcm_init_avx(ctx->Htable, ctx->H.u); ctx->gmult = gcm_gmult_avx; - ctx->ghash = gcm_ghash_avx; + CTX__GHASH(gcm_ghash_avx); } else { gcm_init_clmul(ctx->Htable, ctx->H.u); ctx->gmult = gcm_gmult_clmul; - ctx->ghash = gcm_ghash_clmul; + CTX__GHASH(gcm_ghash_clmul); } return; } @@ -825,66 +769,59 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) if (OPENSSL_ia32cap_P[0] & (1 << 23)) { /* check MMX bit */ # endif ctx->gmult = gcm_gmult_4bit_mmx; - ctx->ghash = gcm_ghash_4bit_mmx; + CTX__GHASH(gcm_ghash_4bit_mmx); } else { ctx->gmult = gcm_gmult_4bit_x86; - ctx->ghash = gcm_ghash_4bit_x86; + CTX__GHASH(gcm_ghash_4bit_x86); } # else ctx->gmult = gcm_gmult_4bit; - ctx->ghash = gcm_ghash_4bit; + CTX__GHASH(gcm_ghash_4bit); # endif # elif defined(GHASH_ASM_ARM) # ifdef PMULL_CAPABLE if (PMULL_CAPABLE) { gcm_init_v8(ctx->Htable, ctx->H.u); ctx->gmult = gcm_gmult_v8; - ctx->ghash = gcm_ghash_v8; + CTX__GHASH(gcm_ghash_v8); } else # endif # ifdef NEON_CAPABLE if (NEON_CAPABLE) { gcm_init_neon(ctx->Htable, ctx->H.u); ctx->gmult = gcm_gmult_neon; - ctx->ghash = gcm_ghash_neon; + CTX__GHASH(gcm_ghash_neon); } else # endif { gcm_init_4bit(ctx->Htable, ctx->H.u); ctx->gmult = gcm_gmult_4bit; -# if defined(GHASH) - ctx->ghash = gcm_ghash_4bit; -# else - ctx->ghash = NULL; -# endif + CTX__GHASH(gcm_ghash_4bit); } # elif defined(GHASH_ASM_SPARC) if (OPENSSL_sparcv9cap_P[0] & SPARCV9_VIS3) { gcm_init_vis3(ctx->Htable, ctx->H.u); ctx->gmult = gcm_gmult_vis3; - ctx->ghash = gcm_ghash_vis3; + CTX__GHASH(gcm_ghash_vis3); } else { gcm_init_4bit(ctx->Htable, ctx->H.u); ctx->gmult = gcm_gmult_4bit; - ctx->ghash = gcm_ghash_4bit; + CTX__GHASH(gcm_ghash_4bit); } # elif defined(GHASH_ASM_PPC) if (OPENSSL_ppccap_P & PPC_CRYPTO207) { gcm_init_p8(ctx->Htable, ctx->H.u); ctx->gmult = gcm_gmult_p8; - ctx->ghash = gcm_ghash_p8; + CTX__GHASH(gcm_ghash_p8); } else { gcm_init_4bit(ctx->Htable, ctx->H.u); ctx->gmult = gcm_gmult_4bit; -# if defined(GHASH) - ctx->ghash = gcm_ghash_4bit; -# else - ctx->ghash = NULL; -# endif + CTX__GHASH(gcm_ghash_4bit); } # else gcm_init_4bit(ctx->Htable, ctx->H.u); # endif +# undef CTX__GHASH #endif } @@ -894,9 +831,7 @@ void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, const union { long one; char little; - } is_endian = { - 1 - }; + } is_endian = { 1 }; unsigned int ctr; #ifdef GCM_FUNCREF_4BIT void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; @@ -1040,9 +975,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const union { long one; char little; - } is_endian = { - 1 - }; + } is_endian = { 1 }; unsigned int n, ctr; size_t i; u64 mlen = ctx->len.u[1]; @@ -1050,15 +983,12 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, void *key = ctx->key; #ifdef GCM_FUNCREF_4BIT void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; -# ifdef GHASH +# if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len) = ctx->ghash; # endif #endif -#if 0 - n = (unsigned int)mlen % 16; /* alternative to ctx->mres */ -#endif mlen += len; if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) return -1; @@ -1100,7 +1030,8 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, if (((size_t)in | (size_t)out) % sizeof(size_t) != 0) break; # endif -# if defined(GHASH) && defined(GHASH_CHUNK) +# if defined(GHASH) +# if defined(GHASH_CHUNK) while (len >= GHASH_CHUNK) { size_t j = GHASH_CHUNK; @@ -1111,11 +1042,11 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; if (is_endian.little) -# ifdef BSWAP4 +# ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); -# else +# else PUTU32(ctx->Yi.c + 12, ctr); -# endif +# endif else ctx->Yi.d[3] = ctr; for (i = 0; i < 16 / sizeof(size_t); ++i) @@ -1127,6 +1058,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK); len -= GHASH_CHUNK; } +# endif if ((i = (len & (size_t)-16))) { size_t j = i; @@ -1227,9 +1159,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const union { long one; char little; - } is_endian = { - 1 - }; + } is_endian = { 1 }; unsigned int n, ctr; size_t i; u64 mlen = ctx->len.u[1]; @@ -1237,7 +1167,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, void *key = ctx->key; #ifdef GCM_FUNCREF_4BIT void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; -# ifdef GHASH +# if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len) = ctx->ghash; # endif @@ -1286,7 +1216,8 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, if (((size_t)in | (size_t)out) % sizeof(size_t) != 0) break; # endif -# if defined(GHASH) && defined(GHASH_CHUNK) +# if defined(GHASH) +# if defined(GHASH_CHUNK) while (len >= GHASH_CHUNK) { size_t j = GHASH_CHUNK; @@ -1298,11 +1229,11 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; if (is_endian.little) -# ifdef BSWAP4 +# ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); -# else +# else PUTU32(ctx->Yi.c + 12, ctr); -# endif +# endif else ctx->Yi.d[3] = ctr; for (i = 0; i < 16 / sizeof(size_t); ++i) @@ -1313,6 +1244,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, } len -= GHASH_CHUNK; } +# endif if ((i = (len & (size_t)-16))) { GHASH(ctx, in, i); while (len >= 16) { @@ -1416,23 +1348,24 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const unsigned char *in, unsigned char *out, size_t len, ctr128_f stream) { +#if defined(OPENSSL_SMALL_FOOTPRINT) + return CRYPTO_gcm128_encrypt(ctx, in, out, len); +#else const union { long one; char little; - } is_endian = { - 1 - }; + } is_endian = { 1 }; unsigned int n, ctr; size_t i; u64 mlen = ctx->len.u[1]; void *key = ctx->key; -#ifdef GCM_FUNCREF_4BIT +# ifdef GCM_FUNCREF_4BIT void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; -# ifdef GHASH +# ifdef GHASH void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len) = ctx->ghash; +# endif # endif -#endif mlen += len; if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) @@ -1446,11 +1379,11 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, } if (is_endian.little) -#ifdef BSWAP4 +# ifdef BSWAP4 ctr = BSWAP4(ctx->Yi.d[3]); -#else +# else ctr = GETU32(ctx->Yi.c + 12); -#endif +# endif else ctr = ctx->Yi.d[3]; @@ -1468,16 +1401,16 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, return 0; } } -#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) +# if defined(GHASH) && defined(GHASH_CHUNK) while (len >= GHASH_CHUNK) { (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); ctr += GHASH_CHUNK / 16; if (is_endian.little) -# ifdef BSWAP4 +# ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); -# else +# else PUTU32(ctx->Yi.c + 12, ctr); -# endif +# endif else ctx->Yi.d[3] = ctr; GHASH(ctx, out, GHASH_CHUNK); @@ -1485,43 +1418,43 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, in += GHASH_CHUNK; len -= GHASH_CHUNK; } -#endif +# endif if ((i = (len & (size_t)-16))) { size_t j = i / 16; (*stream) (in, out, j, key, ctx->Yi.c); ctr += (unsigned int)j; if (is_endian.little) -#ifdef BSWAP4 +# ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); -#else +# else PUTU32(ctx->Yi.c + 12, ctr); -#endif +# endif else ctx->Yi.d[3] = ctr; in += i; len -= i; -#if defined(GHASH) +# if defined(GHASH) GHASH(ctx, out, i); out += i; -#else +# else while (j--) { for (i = 0; i < 16; ++i) ctx->Xi.c[i] ^= out[i]; GCM_MUL(ctx, Xi); out += 16; } -#endif +# endif } if (len) { (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; if (is_endian.little) -#ifdef BSWAP4 +# ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); -#else +# else PUTU32(ctx->Yi.c + 12, ctr); -#endif +# endif else ctx->Yi.d[3] = ctr; while (len--) { @@ -1532,29 +1465,31 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, ctx->mres = n; return 0; +#endif } int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const unsigned char *in, unsigned char *out, size_t len, ctr128_f stream) { +#if defined(OPENSSL_SMALL_FOOTPRINT) + return CRYPTO_gcm128_decrypt(ctx, in, out, len); +#else const union { long one; char little; - } is_endian = { - 1 - }; + } is_endian = { 1 }; unsigned int n, ctr; size_t i; u64 mlen = ctx->len.u[1]; void *key = ctx->key; -#ifdef GCM_FUNCREF_4BIT +# ifdef GCM_FUNCREF_4BIT void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; -# ifdef GHASH +# ifdef GHASH void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len) = ctx->ghash; +# endif # endif -#endif mlen += len; if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) @@ -1568,11 +1503,11 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, } if (is_endian.little) -#ifdef BSWAP4 +# ifdef BSWAP4 ctr = BSWAP4(ctx->Yi.d[3]); -#else +# else ctr = GETU32(ctx->Yi.c + 12); -#endif +# endif else ctr = ctx->Yi.d[3]; @@ -1592,30 +1527,30 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, return 0; } } -#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) +# if defined(GHASH) && defined(GHASH_CHUNK) while (len >= GHASH_CHUNK) { GHASH(ctx, in, GHASH_CHUNK); (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); ctr += GHASH_CHUNK / 16; if (is_endian.little) -# ifdef BSWAP4 +# ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); -# else +# else PUTU32(ctx->Yi.c + 12, ctr); -# endif +# endif else ctx->Yi.d[3] = ctr; out += GHASH_CHUNK; in += GHASH_CHUNK; len -= GHASH_CHUNK; } -#endif +# endif if ((i = (len & (size_t)-16))) { size_t j = i / 16; -#if defined(GHASH) +# if defined(GHASH) GHASH(ctx, in, i); -#else +# else while (j--) { size_t k; for (k = 0; k < 16; ++k) @@ -1625,15 +1560,15 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, } j = i / 16; in -= i; -#endif +# endif (*stream) (in, out, j, key, ctx->Yi.c); ctr += (unsigned int)j; if (is_endian.little) -#ifdef BSWAP4 +# ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); -#else +# else PUTU32(ctx->Yi.c + 12, ctr); -#endif +# endif else ctx->Yi.d[3] = ctr; out += i; @@ -1644,11 +1579,11 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; if (is_endian.little) -#ifdef BSWAP4 +# ifdef BSWAP4 ctx->Yi.d[3] = BSWAP4(ctr); -#else +# else PUTU32(ctx->Yi.c + 12, ctr); -#endif +# endif else ctx->Yi.d[3] = ctr; while (len--) { @@ -1661,6 +1596,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, ctx->mres = n; return 0; +#endif } int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, @@ -1669,9 +1605,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, const union { long one; char little; - } is_endian = { - 1 - }; + } is_endian = { 1 }; u64 alen = ctx->len.u[0] << 3; u64 clen = ctx->len.u[1] << 3; #ifdef GCM_FUNCREF_4BIT @@ -1720,7 +1654,7 @@ GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block) { GCM128_CONTEXT *ret; - if ((ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT)))) + if ((ret = OPENSSL_malloc(sizeof(*ret))) != NULL) CRYPTO_gcm128_init(ret, key, block); return ret; @@ -1728,10 +1662,7 @@ GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block) void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx) { - if (ctx) { - OPENSSL_cleanse(ctx, sizeof(*ctx)); - OPENSSL_free(ctx); - } + OPENSSL_clear_free(ctx, sizeof(*ctx)); } #if defined(SELFTEST) diff --git a/Cryptlib/OpenSSL/crypto/modes/modes_lcl.h b/Cryptlib/OpenSSL/crypto/modes/modes_lcl.h index fe14ec70..7a1603bf 100644 --- a/Cryptlib/OpenSSL/crypto/modes/modes_lcl.h +++ b/Cryptlib/OpenSSL/crypto/modes/modes_lcl.h @@ -1,8 +1,10 @@ -/* ==================================================================== - * Copyright (c) 2010 The OpenSSL Project. All rights reserved. +/* + * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved. * - * Redistribution and use is governed by OpenSSL license. - * ==================================================================== + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #include <openssl/modes.h> @@ -141,3 +143,43 @@ struct ccm128_context { block128_f block; void *key; }; + +#ifndef OPENSSL_NO_OCB + +typedef union { + u64 a[2]; + unsigned char c[16]; +} OCB_BLOCK; +# define ocb_block16_xor(in1,in2,out) \ + ( (out)->a[0]=(in1)->a[0]^(in2)->a[0], \ + (out)->a[1]=(in1)->a[1]^(in2)->a[1] ) +# if STRICT_ALIGNMENT +# define ocb_block16_xor_misaligned(in1,in2,out) \ + ocb_block_xor((in1)->c,(in2)->c,16,(out)->c) +# else +# define ocb_block16_xor_misaligned ocb_block16_xor +# endif + +struct ocb128_context { + /* Need both encrypt and decrypt key schedules for decryption */ + block128_f encrypt; + block128_f decrypt; + void *keyenc; + void *keydec; + ocb128_f stream; /* direction dependent */ + /* Key dependent variables. Can be reused if key remains the same */ + size_t l_index; + size_t max_l_index; + OCB_BLOCK l_star; + OCB_BLOCK l_dollar; + OCB_BLOCK *l; + /* Must be reset for each session */ + u64 blocks_hashed; + u64 blocks_processed; + OCB_BLOCK tag; + OCB_BLOCK offset_aad; + OCB_BLOCK sum; + OCB_BLOCK offset; + OCB_BLOCK checksum; +}; +#endif /* OPENSSL_NO_OCB */ diff --git a/Cryptlib/OpenSSL/crypto/modes/ocb128.c b/Cryptlib/OpenSSL/crypto/modes/ocb128.c new file mode 100644 index 00000000..c3bd13bb --- /dev/null +++ b/Cryptlib/OpenSSL/crypto/modes/ocb128.c @@ -0,0 +1,568 @@ +/* + * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <string.h> +#include <openssl/crypto.h> +#include "modes_lcl.h" + +#ifndef OPENSSL_NO_OCB + +/* + * Calculate the number of binary trailing zero's in any given number + */ +static u32 ocb_ntz(u64 n) +{ + u32 cnt = 0; + + /* + * We do a right-to-left simple sequential search. This is surprisingly + * efficient as the distribution of trailing zeros is not uniform, + * e.g. the number of possible inputs with no trailing zeros is equal to + * the number with 1 or more; the number with exactly 1 is equal to the + * number with 2 or more, etc. Checking the last two bits covers 75% of + * all numbers. Checking the last three covers 87.5% + */ + while (!(n & 1)) { + n >>= 1; + cnt++; + } + return cnt; +} + +/* + * Shift a block of 16 bytes left by shift bits + */ +static void ocb_block_lshift(const unsigned char *in, size_t shift, + unsigned char *out) +{ + unsigned char shift_mask; + int i; + unsigned char mask[15]; + + shift_mask = 0xff; + shift_mask <<= (8 - shift); + for (i = 15; i >= 0; i--) { + if (i > 0) { + mask[i - 1] = in[i] & shift_mask; + mask[i - 1] >>= 8 - shift; + } + out[i] = in[i] << shift; + + if (i != 15) { + out[i] ^= mask[i]; + } + } +} + +/* + * Perform a "double" operation as per OCB spec + */ +static void ocb_double(OCB_BLOCK *in, OCB_BLOCK *out) +{ + unsigned char mask; + + /* + * Calculate the mask based on the most significant bit. There are more + * efficient ways to do this - but this way is constant time + */ + mask = in->c[0] & 0x80; + mask >>= 7; + mask *= 135; + + ocb_block_lshift(in->c, 1, out->c); + + out->c[15] ^= mask; +} + +/* + * Perform an xor on in1 and in2 - each of len bytes. Store result in out + */ +static void ocb_block_xor(const unsigned char *in1, + const unsigned char *in2, size_t len, + unsigned char *out) +{ + size_t i; + for (i = 0; i < len; i++) { + out[i] = in1[i] ^ in2[i]; + } +} + +/* + * Lookup L_index in our lookup table. If we haven't already got it we need to + * calculate it + */ +static OCB_BLOCK *ocb_lookup_l(OCB128_CONTEXT *ctx, size_t idx) +{ + size_t l_index = ctx->l_index; + + if (idx <= l_index) { + return ctx->l + idx; + } + + /* We don't have it - so calculate it */ + if (idx >= ctx->max_l_index) { + void *tmp_ptr; + /* + * Each additional entry allows to process almost double as + * much data, so that in linear world the table will need to + * be expanded with smaller and smaller increments. Originally + * it was doubling in size, which was a waste. Growing it + * linearly is not formally optimal, but is simpler to implement. + * We grow table by minimally required 4*n that would accommodate + * the index. + */ + ctx->max_l_index += (idx - ctx->max_l_index + 4) & ~3; + tmp_ptr = + OPENSSL_realloc(ctx->l, ctx->max_l_index * sizeof(OCB_BLOCK)); + if (tmp_ptr == NULL) /* prevent ctx->l from being clobbered */ + return NULL; + ctx->l = tmp_ptr; + } + while (l_index < idx) { + ocb_double(ctx->l + l_index, ctx->l + l_index + 1); + l_index++; + } + ctx->l_index = l_index; + + return ctx->l + idx; +} + +/* + * Create a new OCB128_CONTEXT + */ +OCB128_CONTEXT *CRYPTO_ocb128_new(void *keyenc, void *keydec, + block128_f encrypt, block128_f decrypt, + ocb128_f stream) +{ + OCB128_CONTEXT *octx; + int ret; + + if ((octx = OPENSSL_malloc(sizeof(*octx))) != NULL) { + ret = CRYPTO_ocb128_init(octx, keyenc, keydec, encrypt, decrypt, + stream); + if (ret) + return octx; + OPENSSL_free(octx); + } + + return NULL; +} + +/* + * Initialise an existing OCB128_CONTEXT + */ +int CRYPTO_ocb128_init(OCB128_CONTEXT *ctx, void *keyenc, void *keydec, + block128_f encrypt, block128_f decrypt, + ocb128_f stream) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->l_index = 0; + ctx->max_l_index = 5; + ctx->l = OPENSSL_malloc(ctx->max_l_index * 16); + if (ctx->l == NULL) + return 0; + + /* + * We set both the encryption and decryption key schedules - decryption + * needs both. Don't really need decryption schedule if only doing + * encryption - but it simplifies things to take it anyway + */ + ctx->encrypt = encrypt; + ctx->decrypt = decrypt; + ctx->stream = stream; + ctx->keyenc = keyenc; + ctx->keydec = keydec; + + /* L_* = ENCIPHER(K, zeros(128)) */ + ctx->encrypt(ctx->l_star.c, ctx->l_star.c, ctx->keyenc); + + /* L_$ = double(L_*) */ + ocb_double(&ctx->l_star, &ctx->l_dollar); + + /* L_0 = double(L_$) */ + ocb_double(&ctx->l_dollar, ctx->l); + + /* L_{i} = double(L_{i-1}) */ + ocb_double(ctx->l, ctx->l+1); + ocb_double(ctx->l+1, ctx->l+2); + ocb_double(ctx->l+2, ctx->l+3); + ocb_double(ctx->l+3, ctx->l+4); + ctx->l_index = 4; /* enough to process up to 496 bytes */ + + return 1; +} + +/* + * Copy an OCB128_CONTEXT object + */ +int CRYPTO_ocb128_copy_ctx(OCB128_CONTEXT *dest, OCB128_CONTEXT *src, + void *keyenc, void *keydec) +{ + memcpy(dest, src, sizeof(OCB128_CONTEXT)); + if (keyenc) + dest->keyenc = keyenc; + if (keydec) + dest->keydec = keydec; + if (src->l) { + dest->l = OPENSSL_malloc(src->max_l_index * 16); + if (dest->l == NULL) + return 0; + memcpy(dest->l, src->l, (src->l_index + 1) * 16); + } + return 1; +} + +/* + * Set the IV to be used for this operation. Must be 1 - 15 bytes. + */ +int CRYPTO_ocb128_setiv(OCB128_CONTEXT *ctx, const unsigned char *iv, + size_t len, size_t taglen) +{ + unsigned char ktop[16], tmp[16], mask; + unsigned char stretch[24], nonce[16]; + size_t bottom, shift; + + /* + * Spec says IV is 120 bits or fewer - it allows non byte aligned lengths. + * We don't support this at this stage + */ + if ((len > 15) || (len < 1) || (taglen > 16) || (taglen < 1)) { + return -1; + } + + /* Nonce = num2str(TAGLEN mod 128,7) || zeros(120-bitlen(N)) || 1 || N */ + nonce[0] = ((taglen * 8) % 128) << 1; + memset(nonce + 1, 0, 15); + memcpy(nonce + 16 - len, iv, len); + nonce[15 - len] |= 1; + + /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */ + memcpy(tmp, nonce, 16); + tmp[15] &= 0xc0; + ctx->encrypt(tmp, ktop, ctx->keyenc); + + /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */ + memcpy(stretch, ktop, 16); + ocb_block_xor(ktop, ktop + 1, 8, stretch + 16); + + /* bottom = str2num(Nonce[123..128]) */ + bottom = nonce[15] & 0x3f; + + /* Offset_0 = Stretch[1+bottom..128+bottom] */ + shift = bottom % 8; + ocb_block_lshift(stretch + (bottom / 8), shift, ctx->offset.c); + mask = 0xff; + mask <<= 8 - shift; + ctx->offset.c[15] |= + (*(stretch + (bottom / 8) + 16) & mask) >> (8 - shift); + + return 1; +} + +/* + * Provide any AAD. This can be called multiple times. Only the final time can + * have a partial block + */ +int CRYPTO_ocb128_aad(OCB128_CONTEXT *ctx, const unsigned char *aad, + size_t len) +{ + u64 i, all_num_blocks; + size_t num_blocks, last_len; + OCB_BLOCK tmp1; + OCB_BLOCK tmp2; + + /* Calculate the number of blocks of AAD provided now, and so far */ + num_blocks = len / 16; + all_num_blocks = num_blocks + ctx->blocks_hashed; + + /* Loop through all full blocks of AAD */ + for (i = ctx->blocks_hashed + 1; i <= all_num_blocks; i++) { + OCB_BLOCK *lookup; + OCB_BLOCK *aad_block; + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ + lookup = ocb_lookup_l(ctx, ocb_ntz(i)); + if (lookup == NULL) + return 0; + ocb_block16_xor(&ctx->offset_aad, lookup, &ctx->offset_aad); + + /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ + aad_block = (OCB_BLOCK *)(aad + ((i - ctx->blocks_hashed - 1) * 16)); + ocb_block16_xor(&ctx->offset_aad, aad_block, &tmp1); + ctx->encrypt(tmp1.c, tmp2.c, ctx->keyenc); + ocb_block16_xor(&ctx->sum, &tmp2, &ctx->sum); + } + + /* + * Check if we have any partial blocks left over. This is only valid in the + * last call to this function + */ + last_len = len % 16; + + if (last_len > 0) { + /* Offset_* = Offset_m xor L_* */ + ocb_block16_xor(&ctx->offset_aad, &ctx->l_star, &ctx->offset_aad); + + /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */ + memset(&tmp1, 0, 16); + memcpy(&tmp1, aad + (num_blocks * 16), last_len); + ((unsigned char *)&tmp1)[last_len] = 0x80; + ocb_block16_xor(&ctx->offset_aad, &tmp1, &tmp2); + + /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */ + ctx->encrypt(tmp2.c, tmp1.c, ctx->keyenc); + ocb_block16_xor(&ctx->sum, &tmp1, &ctx->sum); + } + + ctx->blocks_hashed = all_num_blocks; + + return 1; +} + +/* + * Provide any data to be encrypted. This can be called multiple times. Only + * the final time can have a partial block + */ +int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len) +{ + u64 i, all_num_blocks; + size_t num_blocks, last_len; + OCB_BLOCK tmp1; + OCB_BLOCK tmp2; + OCB_BLOCK pad; + + /* + * Calculate the number of blocks of data to be encrypted provided now, and + * so far + */ + num_blocks = len / 16; + all_num_blocks = num_blocks + ctx->blocks_processed; + + if (num_blocks && all_num_blocks == (size_t)all_num_blocks + && ctx->stream != NULL) { + size_t max_idx = 0, top = (size_t)all_num_blocks; + + /* + * See how many L_{i} entries we need to process data at hand + * and pre-compute missing entries in the table [if any]... + */ + while (top >>= 1) + max_idx++; + if (ocb_lookup_l(ctx, max_idx) == NULL) + return 0; + + ctx->stream(in, out, num_blocks, ctx->keyenc, + (size_t)ctx->blocks_processed + 1, ctx->offset.c, + (const unsigned char (*)[16])ctx->l, ctx->checksum.c); + } else { + /* Loop through all full blocks to be encrypted */ + for (i = ctx->blocks_processed + 1; i <= all_num_blocks; i++) { + OCB_BLOCK *lookup; + OCB_BLOCK *inblock; + OCB_BLOCK *outblock; + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ + lookup = ocb_lookup_l(ctx, ocb_ntz(i)); + if (lookup == NULL) + return 0; + ocb_block16_xor(&ctx->offset, lookup, &ctx->offset); + + /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ + inblock = + (OCB_BLOCK *)(in + ((i - ctx->blocks_processed - 1) * 16)); + ocb_block16_xor_misaligned(&ctx->offset, inblock, &tmp1); + /* Checksum_i = Checksum_{i-1} xor P_i */ + ocb_block16_xor_misaligned(&ctx->checksum, inblock, &ctx->checksum); + ctx->encrypt(tmp1.c, tmp2.c, ctx->keyenc); + outblock = + (OCB_BLOCK *)(out + ((i - ctx->blocks_processed - 1) * 16)); + ocb_block16_xor_misaligned(&ctx->offset, &tmp2, outblock); + } + } + + /* + * Check if we have any partial blocks left over. This is only valid in the + * last call to this function + */ + last_len = len % 16; + + if (last_len > 0) { + /* Offset_* = Offset_m xor L_* */ + ocb_block16_xor(&ctx->offset, &ctx->l_star, &ctx->offset); + + /* Pad = ENCIPHER(K, Offset_*) */ + ctx->encrypt(ctx->offset.c, pad.c, ctx->keyenc); + + /* C_* = P_* xor Pad[1..bitlen(P_*)] */ + ocb_block_xor(in + (len / 16) * 16, (unsigned char *)&pad, last_len, + out + (num_blocks * 16)); + + /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */ + memset(&tmp1, 0, 16); + memcpy(&tmp1, in + (len / 16) * 16, last_len); + ((unsigned char *)(&tmp1))[last_len] = 0x80; + ocb_block16_xor(&ctx->checksum, &tmp1, &ctx->checksum); + } + + ctx->blocks_processed = all_num_blocks; + + return 1; +} + +/* + * Provide any data to be decrypted. This can be called multiple times. Only + * the final time can have a partial block + */ +int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len) +{ + u64 i, all_num_blocks; + size_t num_blocks, last_len; + OCB_BLOCK tmp1; + OCB_BLOCK tmp2; + OCB_BLOCK pad; + + /* + * Calculate the number of blocks of data to be decrypted provided now, and + * so far + */ + num_blocks = len / 16; + all_num_blocks = num_blocks + ctx->blocks_processed; + + if (num_blocks && all_num_blocks == (size_t)all_num_blocks + && ctx->stream != NULL) { + size_t max_idx = 0, top = (size_t)all_num_blocks; + + /* + * See how many L_{i} entries we need to process data at hand + * and pre-compute missing entries in the table [if any]... + */ + while (top >>= 1) + max_idx++; + if (ocb_lookup_l(ctx, max_idx) == NULL) + return 0; + + ctx->stream(in, out, num_blocks, ctx->keydec, + (size_t)ctx->blocks_processed + 1, ctx->offset.c, + (const unsigned char (*)[16])ctx->l, ctx->checksum.c); + } else { + /* Loop through all full blocks to be decrypted */ + for (i = ctx->blocks_processed + 1; i <= all_num_blocks; i++) { + OCB_BLOCK *inblock; + OCB_BLOCK *outblock; + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ + OCB_BLOCK *lookup = ocb_lookup_l(ctx, ocb_ntz(i)); + if (lookup == NULL) + return 0; + ocb_block16_xor(&ctx->offset, lookup, &ctx->offset); + + /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ + inblock = + (OCB_BLOCK *)(in + ((i - ctx->blocks_processed - 1) * 16)); + ocb_block16_xor_misaligned(&ctx->offset, inblock, &tmp1); + ctx->decrypt(tmp1.c, tmp2.c, ctx->keydec); + outblock = + (OCB_BLOCK *)(out + ((i - ctx->blocks_processed - 1) * 16)); + ocb_block16_xor_misaligned(&ctx->offset, &tmp2, outblock); + + /* Checksum_i = Checksum_{i-1} xor P_i */ + ocb_block16_xor_misaligned(&ctx->checksum, outblock, &ctx->checksum); + } + } + + /* + * Check if we have any partial blocks left over. This is only valid in the + * last call to this function + */ + last_len = len % 16; + + if (last_len > 0) { + /* Offset_* = Offset_m xor L_* */ + ocb_block16_xor(&ctx->offset, &ctx->l_star, &ctx->offset); + + /* Pad = ENCIPHER(K, Offset_*) */ + ctx->encrypt(ctx->offset.c, pad.c, ctx->keyenc); + + /* P_* = C_* xor Pad[1..bitlen(C_*)] */ + ocb_block_xor(in + (len / 16) * 16, (unsigned char *)&pad, last_len, + out + (num_blocks * 16)); + + /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */ + memset(&tmp1, 0, 16); + memcpy(&tmp1, out + (len / 16) * 16, last_len); + ((unsigned char *)(&tmp1))[last_len] = 0x80; + ocb_block16_xor(&ctx->checksum, &tmp1, &ctx->checksum); + } + + ctx->blocks_processed = all_num_blocks; + + return 1; +} + +/* + * Calculate the tag and verify it against the supplied tag + */ +int CRYPTO_ocb128_finish(OCB128_CONTEXT *ctx, const unsigned char *tag, + size_t len) +{ + OCB_BLOCK tmp1, tmp2; + + /* + * Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) + */ + ocb_block16_xor(&ctx->checksum, &ctx->offset, &tmp1); + ocb_block16_xor(&tmp1, &ctx->l_dollar, &tmp2); + ctx->encrypt(tmp2.c, tmp1.c, ctx->keyenc); + ocb_block16_xor(&tmp1, &ctx->sum, &ctx->tag); + + if (len > 16 || len < 1) { + return -1; + } + + /* Compare the tag if we've been given one */ + if (tag) + return CRYPTO_memcmp(&ctx->tag, tag, len); + else + return -1; +} + +/* + * Retrieve the calculated tag + */ +int CRYPTO_ocb128_tag(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len) +{ + if (len > 16 || len < 1) { + return -1; + } + + /* Calculate the tag */ + CRYPTO_ocb128_finish(ctx, NULL, 0); + + /* Copy the tag into the supplied buffer */ + memcpy(tag, &ctx->tag, len); + + return 1; +} + +/* + * Release all resources + */ +void CRYPTO_ocb128_cleanup(OCB128_CONTEXT *ctx) +{ + if (ctx) { + OPENSSL_clear_free(ctx->l, ctx->max_l_index * 16); + OPENSSL_cleanse(ctx, sizeof(*ctx)); + } +} + +#endif /* OPENSSL_NO_OCB */ diff --git a/Cryptlib/OpenSSL/crypto/modes/ofb128.c b/Cryptlib/OpenSSL/crypto/modes/ofb128.c index 4dbaccd7..83092564 100644 --- a/Cryptlib/OpenSSL/crypto/modes/ofb128.c +++ b/Cryptlib/OpenSSL/crypto/modes/ofb128.c @@ -1,64 +1,16 @@ -/* ==================================================================== - * Copyright (c) 2008 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 - * openssl-core@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. - * ==================================================================== +/* + * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #include <openssl/crypto.h> #include "modes_lcl.h" #include <string.h> -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include <assert.h> - /* * The input and output encrypted as though 128bit ofb mode is being used. * The extra state information to record how much of the 128bit block we have @@ -71,8 +23,6 @@ void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, unsigned int n; size_t l = 0; - assert(in && out && key && ivec && num); - n = *num; #if !defined(OPENSSL_SMALL_FOOTPRINT) diff --git a/Cryptlib/OpenSSL/crypto/modes/wrap128.c b/Cryptlib/OpenSSL/crypto/modes/wrap128.c index 38497837..46809a0e 100644 --- a/Cryptlib/OpenSSL/crypto/modes/wrap128.c +++ b/Cryptlib/OpenSSL/crypto/modes/wrap128.c @@ -1,70 +1,50 @@ -/* crypto/modes/wrap128.c */ /* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2013 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. + * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. * - * 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/)" + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/** Beware! * - * 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. - * ==================================================================== + * Following wrapping modes were designed for AES but this implementation + * allows you to use them for any 128 bit block cipher. */ -#include "cryptlib.h" +#include "internal/cryptlib.h" #include <openssl/modes.h> +/** RFC 3394 section 2.2.3.1 Default Initial Value */ static const unsigned char default_iv[] = { 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, }; -/* - * Input size limit: lower than maximum of standards but far larger than - * anything that will be used in practice. +/** RFC 5649 section 3 Alternative Initial Value 32-bit constant */ +static const unsigned char default_aiv[] = { + 0xA6, 0x59, 0x59, 0xA6 +}; + +/** Input size limit: lower than maximum of standards but far larger than + * anything that will be used in practice. */ #define CRYPTO128_WRAP_MAX (1UL << 31) +/** Wrapping according to RFC 3394 section 2.2.1. + * + * @param[in] key Key value. + * @param[in] iv IV value. Length = 8 bytes. NULL = use default_iv. + * @param[in] in Plaintext as n 64-bit blocks, n >= 2. + * @param[in] inlen Length of in. + * @param[out] out Ciphertext. Minimal buffer length = (inlen + 8) bytes. + * Input and output buffers can overlap if block function + * supports that. + * @param[in] block Block processing function. + * @return 0 if inlen does not consist of n 64-bit blocks, n >= 2. + * or if inlen > CRYPTO128_WRAP_MAX. + * Output length if wrapping succeeded. + */ size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, unsigned char *out, const unsigned char *in, size_t inlen, @@ -72,7 +52,7 @@ size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, { unsigned char *A, B[16], *R; size_t i, j, t; - if ((inlen & 0x7) || (inlen < 8) || (inlen > CRYPTO128_WRAP_MAX)) + if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX)) return 0; A = B; t = 1; @@ -100,10 +80,26 @@ size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, return inlen + 8; } -size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, - unsigned char *out, - const unsigned char *in, size_t inlen, - block128_f block) +/** Unwrapping according to RFC 3394 section 2.2.2 steps 1-2. + * The IV check (step 3) is responsibility of the caller. + * + * @param[in] key Key value. + * @param[out] iv Unchecked IV value. Minimal buffer length = 8 bytes. + * @param[out] out Plaintext without IV. + * Minimal buffer length = (inlen - 8) bytes. + * Input and output buffers can overlap if block function + * supports that. + * @param[in] in Ciphertext as n 64-bit blocks. + * @param[in] inlen Length of in. + * @param[in] block Block processing function. + * @return 0 if inlen is out of range [24, CRYPTO128_WRAP_MAX] + * or if inlen is not a multiple of 8. + * Output length otherwise. + */ +static size_t crypto_128_unwrap_raw(void *key, unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block) { unsigned char *A, B[16], *R; size_t i, j, t; @@ -128,11 +124,206 @@ size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, memcpy(R, B + 8, 8); } } + memcpy(iv, A, 8); + return inlen; +} + +/** Unwrapping according to RFC 3394 section 2.2.2, including the IV check. + * The first block of plaintext has to match the supplied IV, otherwise an + * error is returned. + * + * @param[in] key Key value. + * @param[out] iv IV value to match against. Length = 8 bytes. + * NULL = use default_iv. + * @param[out] out Plaintext without IV. + * Minimal buffer length = (inlen - 8) bytes. + * Input and output buffers can overlap if block function + * supports that. + * @param[in] in Ciphertext as n 64-bit blocks. + * @param[in] inlen Length of in. + * @param[in] block Block processing function. + * @return 0 if inlen is out of range [24, CRYPTO128_WRAP_MAX] + * or if inlen is not a multiple of 8 + * or if IV doesn't match expected value. + * Output length otherwise. + */ +size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, + unsigned char *out, const unsigned char *in, + size_t inlen, block128_f block) +{ + size_t ret; + unsigned char got_iv[8]; + + ret = crypto_128_unwrap_raw(key, got_iv, out, in, inlen, block); + if (ret == 0) + return 0; + if (!iv) iv = default_iv; - if (memcmp(A, iv, 8)) { + if (CRYPTO_memcmp(got_iv, iv, 8)) { + OPENSSL_cleanse(out, ret); + return 0; + } + return ret; +} + +/** Wrapping according to RFC 5649 section 4.1. + * + * @param[in] key Key value. + * @param[in] icv (Non-standard) IV, 4 bytes. NULL = use default_aiv. + * @param[out] out Ciphertext. Minimal buffer length = (inlen + 15) bytes. + * Input and output buffers can overlap if block function + * supports that. + * @param[in] in Plaintext as n 64-bit blocks, n >= 2. + * @param[in] inlen Length of in. + * @param[in] block Block processing function. + * @return 0 if inlen is out of range [1, CRYPTO128_WRAP_MAX]. + * Output length if wrapping succeeded. + */ +size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block) +{ + /* n: number of 64-bit blocks in the padded key data + * + * If length of plain text is not a multiple of 8, pad the plain text octet + * string on the right with octets of zeros, where final length is the + * smallest multiple of 8 that is greater than length of plain text. + * If length of plain text is a multiple of 8, then there is no padding. */ + const size_t blocks_padded = (inlen + 7) / 8; /* CEILING(m/8) */ + const size_t padded_len = blocks_padded * 8; + const size_t padding_len = padded_len - inlen; + /* RFC 5649 section 3: Alternative Initial Value */ + unsigned char aiv[8]; + int ret; + + /* Section 1: use 32-bit fixed field for plaintext octet length */ + if (inlen == 0 || inlen >= CRYPTO128_WRAP_MAX) + return 0; + + /* Section 3: Alternative Initial Value */ + if (!icv) + memcpy(aiv, default_aiv, 4); + else + memcpy(aiv, icv, 4); /* Standard doesn't mention this. */ + + aiv[4] = (inlen >> 24) & 0xFF; + aiv[5] = (inlen >> 16) & 0xFF; + aiv[6] = (inlen >> 8) & 0xFF; + aiv[7] = inlen & 0xFF; + + if (padded_len == 8) { + /* + * Section 4.1 - special case in step 2: If the padded plaintext + * contains exactly eight octets, then prepend the AIV and encrypt + * the resulting 128-bit block using AES in ECB mode. + */ + memmove(out + 8, in, inlen); + memcpy(out, aiv, 8); + memset(out + 8 + inlen, 0, padding_len); + block(out, out, key); + ret = 16; /* AIV + padded input */ + } else { + memmove(out, in, inlen); + memset(out + inlen, 0, padding_len); /* Section 4.1 step 1 */ + ret = CRYPTO_128_wrap(key, aiv, out, out, padded_len, block); + } + + return ret; +} + +/** Unwrapping according to RFC 5649 section 4.2. + * + * @param[in] key Key value. + * @param[in] icv (Non-standard) IV, 4 bytes. NULL = use default_aiv. + * @param[out] out Plaintext. Minimal buffer length = inlen bytes. + * Input and output buffers can overlap if block function + * supports that. + * @param[in] in Ciphertext as n 64-bit blocks. + * @param[in] inlen Length of in. + * @param[in] block Block processing function. + * @return 0 if inlen is out of range [16, CRYPTO128_WRAP_MAX], + * or if inlen is not a multiple of 8 + * or if IV and message length indicator doesn't match. + * Output length if unwrapping succeeded and IV matches. + */ +size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block) +{ + /* n: number of 64-bit blocks in the padded key data */ + size_t n = inlen / 8 - 1; + size_t padded_len; + size_t padding_len; + size_t ptext_len; + /* RFC 5649 section 3: Alternative Initial Value */ + unsigned char aiv[8]; + static unsigned char zeros[8] = { 0x0 }; + size_t ret; + + /* Section 4.2: Ciphertext length has to be (n+1) 64-bit blocks. */ + if ((inlen & 0x7) != 0 || inlen < 16 || inlen >= CRYPTO128_WRAP_MAX) + return 0; + + memmove(out, in, inlen); + if (inlen == 16) { + /* + * Section 4.2 - special case in step 1: When n=1, the ciphertext + * contains exactly two 64-bit blocks and they are decrypted as a + * single AES block using AES in ECB mode: AIV | P[1] = DEC(K, C[0] | + * C[1]) + */ + block(out, out, key); + memcpy(aiv, out, 8); + /* Remove AIV */ + memmove(out, out + 8, 8); + padded_len = 8; + } else { + padded_len = inlen - 8; + ret = crypto_128_unwrap_raw(key, aiv, out, out, inlen, block); + if (padded_len != ret) { + OPENSSL_cleanse(out, inlen); + return 0; + } + } + + /* + * Section 3: AIV checks: Check that MSB(32,A) = A65959A6. Optionally a + * user-supplied value can be used (even if standard doesn't mention + * this). + */ + if ((!icv && CRYPTO_memcmp(aiv, default_aiv, 4)) + || (icv && CRYPTO_memcmp(aiv, icv, 4))) { OPENSSL_cleanse(out, inlen); return 0; } - return inlen; + + /* + * Check that 8*(n-1) < LSB(32,AIV) <= 8*n. If so, let ptext_len = + * LSB(32,AIV). + */ + + ptext_len = ((unsigned int)aiv[4] << 24) + | ((unsigned int)aiv[5] << 16) + | ((unsigned int)aiv[6] << 8) + | (unsigned int)aiv[7]; + if (8 * (n - 1) >= ptext_len || ptext_len > 8 * n) { + OPENSSL_cleanse(out, inlen); + return 0; + } + + /* + * Check that the rightmost padding_len octets of the output data are + * zero. + */ + padding_len = padded_len - ptext_len; + if (CRYPTO_memcmp(out + ptext_len, zeros, padding_len) != 0) { + OPENSSL_cleanse(out, inlen); + return 0; + } + + /* Section 4.2 step 3: Remove padding */ + return ptext_len; } diff --git a/Cryptlib/OpenSSL/crypto/modes/xts128.c b/Cryptlib/OpenSSL/crypto/modes/xts128.c index 8f2af588..81b1eacd 100644 --- a/Cryptlib/OpenSSL/crypto/modes/xts128.c +++ b/Cryptlib/OpenSSL/crypto/modes/xts128.c @@ -1,63 +1,16 @@ -/* ==================================================================== - * Copyright (c) 2011 The OpenSSL Project. All rights reserved. +/* + * Copyright 2011-2016 The OpenSSL Project Authors. 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 - * openssl-core@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. - * ==================================================================== + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #include <openssl/crypto.h> #include "modes_lcl.h" #include <string.h> -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include <assert.h> - int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16], const unsigned char *inp, unsigned char *out, |