diff options
Diffstat (limited to 'src/lib/libcrypto/modes/ccm128.c')
| -rw-r--r-- | src/lib/libcrypto/modes/ccm128.c | 439 |
1 files changed, 244 insertions, 195 deletions
diff --git a/src/lib/libcrypto/modes/ccm128.c b/src/lib/libcrypto/modes/ccm128.c index 978259e1ba..d1471ee2dd 100644 --- a/src/lib/libcrypto/modes/ccm128.c +++ b/src/lib/libcrypto/modes/ccm128.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ccm128.c,v 1.6 2022/11/26 16:08:53 tb Exp $ */ | 1 | /* $OpenBSD: ccm128.c,v 1.7 2023/07/08 14:55:36 beck Exp $ */ |
| 2 | /* ==================================================================== | 2 | /* ==================================================================== |
| 3 | * Copyright (c) 2011 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 2011 The OpenSSL Project. All rights reserved. |
| 4 | * | 4 | * |
| @@ -7,7 +7,7 @@ | |||
| 7 | * are met: | 7 | * are met: |
| 8 | * | 8 | * |
| 9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright |
| 10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. |
| 11 | * | 11 | * |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in | 13 | * notice, this list of conditions and the following disclaimer in |
| @@ -60,11 +60,12 @@ | |||
| 60 | 60 | ||
| 61 | /* First you setup M and L parameters and pass the key schedule. | 61 | /* First you setup M and L parameters and pass the key schedule. |
| 62 | * This is called once per session setup... */ | 62 | * This is called once per session setup... */ |
| 63 | void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, | 63 | void |
| 64 | unsigned int M,unsigned int L,void *key,block128_f block) | 64 | CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, |
| 65 | unsigned int M, unsigned int L, void *key, block128_f block) | ||
| 65 | { | 66 | { |
| 66 | memset(ctx->nonce.c,0,sizeof(ctx->nonce.c)); | 67 | memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c)); |
| 67 | ctx->nonce.c[0] = ((u8)(L-1)&7) | (u8)(((M-2)/2)&7)<<3; | 68 | ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2)/2) & 7) << 3; |
| 68 | ctx->blocks = 0; | 69 | ctx->blocks = 0; |
| 69 | ctx->block = block; | 70 | ctx->block = block; |
| 70 | ctx->key = key; | 71 | ctx->key = key; |
| @@ -73,79 +74,82 @@ void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, | |||
| 73 | /* !!! Following interfaces are to be called *once* per packet !!! */ | 74 | /* !!! Following interfaces are to be called *once* per packet !!! */ |
| 74 | 75 | ||
| 75 | /* Then you setup per-message nonce and pass the length of the message */ | 76 | /* Then you setup per-message nonce and pass the length of the message */ |
| 76 | int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, | 77 | int |
| 77 | const unsigned char *nonce,size_t nlen,size_t mlen) | 78 | CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, |
| 79 | const unsigned char *nonce, size_t nlen, size_t mlen) | ||
| 78 | { | 80 | { |
| 79 | unsigned int L = ctx->nonce.c[0]&7; /* the L parameter */ | 81 | unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */ |
| 80 | 82 | ||
| 81 | if (nlen<(14-L)) return -1; /* nonce is too short */ | 83 | if (nlen < (14 - L)) |
| 84 | return -1; /* nonce is too short */ | ||
| 82 | 85 | ||
| 83 | if (sizeof(mlen)==8 && L>=3) { | 86 | if (sizeof(mlen) == 8 && L >= 3) { |
| 84 | ctx->nonce.c[8] = (u8)(mlen>>(56%(sizeof(mlen)*8))); | 87 | ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen)*8))); |
| 85 | ctx->nonce.c[9] = (u8)(mlen>>(48%(sizeof(mlen)*8))); | 88 | ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen)*8))); |
| 86 | ctx->nonce.c[10] = (u8)(mlen>>(40%(sizeof(mlen)*8))); | 89 | ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen)*8))); |
| 87 | ctx->nonce.c[11] = (u8)(mlen>>(32%(sizeof(mlen)*8))); | 90 | ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen)*8))); |
| 88 | } | 91 | } else |
| 89 | else | ||
| 90 | ctx->nonce.u[1] = 0; | 92 | ctx->nonce.u[1] = 0; |
| 91 | 93 | ||
| 92 | ctx->nonce.c[12] = (u8)(mlen>>24); | 94 | ctx->nonce.c[12] = (u8)(mlen >> 24); |
| 93 | ctx->nonce.c[13] = (u8)(mlen>>16); | 95 | ctx->nonce.c[13] = (u8)(mlen >> 16); |
| 94 | ctx->nonce.c[14] = (u8)(mlen>>8); | 96 | ctx->nonce.c[14] = (u8)(mlen >> 8); |
| 95 | ctx->nonce.c[15] = (u8)mlen; | 97 | ctx->nonce.c[15] = (u8)mlen; |
| 96 | 98 | ||
| 97 | ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */ | 99 | ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */ |
| 98 | memcpy(&ctx->nonce.c[1],nonce,14-L); | 100 | memcpy(&ctx->nonce.c[1], nonce, 14 - L); |
| 99 | 101 | ||
| 100 | return 0; | 102 | return 0; |
| 101 | } | 103 | } |
| 102 | 104 | ||
| 103 | /* Then you pass additional authentication data, this is optional */ | 105 | /* Then you pass additional authentication data, this is optional */ |
| 104 | void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, | 106 | void |
| 105 | const unsigned char *aad,size_t alen) | 107 | CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, |
| 106 | { unsigned int i; | 108 | const unsigned char *aad, size_t alen) |
| 109 | { | ||
| 110 | unsigned int i; | ||
| 107 | block128_f block = ctx->block; | 111 | block128_f block = ctx->block; |
| 108 | 112 | ||
| 109 | if (alen==0) return; | 113 | if (alen == 0) |
| 114 | return; | ||
| 110 | 115 | ||
| 111 | ctx->nonce.c[0] |= 0x40; /* set Adata flag */ | 116 | ctx->nonce.c[0] |= 0x40; /* set Adata flag */ |
| 112 | (*block)(ctx->nonce.c,ctx->cmac.c,ctx->key), | 117 | (*block)(ctx->nonce.c, ctx->cmac.c, ctx->key), |
| 113 | ctx->blocks++; | 118 | ctx->blocks++; |
| 114 | 119 | ||
| 115 | if (alen<(0x10000-0x100)) { | 120 | if (alen < (0x10000 - 0x100)) { |
| 116 | ctx->cmac.c[0] ^= (u8)(alen>>8); | 121 | ctx->cmac.c[0] ^= (u8)(alen >> 8); |
| 117 | ctx->cmac.c[1] ^= (u8)alen; | 122 | ctx->cmac.c[1] ^= (u8)alen; |
| 118 | i=2; | 123 | i = 2; |
| 119 | } | 124 | } else if (sizeof(alen) == 8 && |
| 120 | else if (sizeof(alen)==8 && alen>=(size_t)1<<(32%(sizeof(alen)*8))) { | 125 | alen >= (size_t)1 << (32 % (sizeof(alen)*8))) { |
| 121 | ctx->cmac.c[0] ^= 0xFF; | 126 | ctx->cmac.c[0] ^= 0xFF; |
| 122 | ctx->cmac.c[1] ^= 0xFF; | 127 | ctx->cmac.c[1] ^= 0xFF; |
| 123 | ctx->cmac.c[2] ^= (u8)(alen>>(56%(sizeof(alen)*8))); | 128 | ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen)*8))); |
| 124 | ctx->cmac.c[3] ^= (u8)(alen>>(48%(sizeof(alen)*8))); | 129 | ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen)*8))); |
| 125 | ctx->cmac.c[4] ^= (u8)(alen>>(40%(sizeof(alen)*8))); | 130 | ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen)*8))); |
| 126 | ctx->cmac.c[5] ^= (u8)(alen>>(32%(sizeof(alen)*8))); | 131 | ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen)*8))); |
| 127 | ctx->cmac.c[6] ^= (u8)(alen>>24); | 132 | ctx->cmac.c[6] ^= (u8)(alen >> 24); |
| 128 | ctx->cmac.c[7] ^= (u8)(alen>>16); | 133 | ctx->cmac.c[7] ^= (u8)(alen >> 16); |
| 129 | ctx->cmac.c[8] ^= (u8)(alen>>8); | 134 | ctx->cmac.c[8] ^= (u8)(alen >> 8); |
| 130 | ctx->cmac.c[9] ^= (u8)alen; | 135 | ctx->cmac.c[9] ^= (u8)alen; |
| 131 | i=10; | 136 | i = 10; |
| 132 | } | 137 | } else { |
| 133 | else { | ||
| 134 | ctx->cmac.c[0] ^= 0xFF; | 138 | ctx->cmac.c[0] ^= 0xFF; |
| 135 | ctx->cmac.c[1] ^= 0xFE; | 139 | ctx->cmac.c[1] ^= 0xFE; |
| 136 | ctx->cmac.c[2] ^= (u8)(alen>>24); | 140 | ctx->cmac.c[2] ^= (u8)(alen >> 24); |
| 137 | ctx->cmac.c[3] ^= (u8)(alen>>16); | 141 | ctx->cmac.c[3] ^= (u8)(alen >> 16); |
| 138 | ctx->cmac.c[4] ^= (u8)(alen>>8); | 142 | ctx->cmac.c[4] ^= (u8)(alen >> 8); |
| 139 | ctx->cmac.c[5] ^= (u8)alen; | 143 | ctx->cmac.c[5] ^= (u8)alen; |
| 140 | i=6; | 144 | i = 6; |
| 141 | } | 145 | } |
| 142 | 146 | ||
| 143 | do { | 147 | do { |
| 144 | for(;i<16 && alen;++i,++aad,--alen) | 148 | for (; i < 16 && alen; ++i, ++aad, --alen) |
| 145 | ctx->cmac.c[i] ^= *aad; | 149 | ctx->cmac.c[i] ^= *aad; |
| 146 | (*block)(ctx->cmac.c,ctx->cmac.c,ctx->key), | 150 | (*block)(ctx->cmac.c, ctx->cmac.c, ctx->key), |
| 147 | ctx->blocks++; | 151 | ctx->blocks++; |
| 148 | i=0; | 152 | i = 0; |
| 149 | } while (alen); | 153 | } while (alen); |
| 150 | } | 154 | } |
| 151 | 155 | ||
| @@ -153,9 +157,11 @@ void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, | |||
| 153 | 157 | ||
| 154 | /* counter part of nonce may not be larger than L*8 bits, | 158 | /* counter part of nonce may not be larger than L*8 bits, |
| 155 | * L is not larger than 8, therefore 64-bit counter... */ | 159 | * L is not larger than 8, therefore 64-bit counter... */ |
| 156 | static void ctr64_inc(unsigned char *counter) { | 160 | static void |
| 157 | unsigned int n=8; | 161 | ctr64_inc(unsigned char *counter) |
| 158 | u8 c; | 162 | { |
| 163 | unsigned int n = 8; | ||
| 164 | u8 c; | ||
| 159 | 165 | ||
| 160 | counter += 8; | 166 | counter += 8; |
| 161 | do { | 167 | do { |
| @@ -163,60 +169,70 @@ static void ctr64_inc(unsigned char *counter) { | |||
| 163 | c = counter[n]; | 169 | c = counter[n]; |
| 164 | ++c; | 170 | ++c; |
| 165 | counter[n] = c; | 171 | counter[n] = c; |
| 166 | if (c) return; | 172 | if (c) |
| 173 | return; | ||
| 167 | } while (n); | 174 | } while (n); |
| 168 | } | 175 | } |
| 169 | 176 | ||
| 170 | int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, | 177 | int |
| 171 | const unsigned char *inp, unsigned char *out, | 178 | CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, |
| 172 | size_t len) | 179 | const unsigned char *inp, unsigned char *out, |
| 180 | size_t len) | ||
| 173 | { | 181 | { |
| 174 | size_t n; | 182 | size_t n; |
| 175 | unsigned int i,L; | 183 | unsigned int i, L; |
| 176 | unsigned char flags0 = ctx->nonce.c[0]; | 184 | unsigned char flags0 = ctx->nonce.c[0]; |
| 177 | block128_f block = ctx->block; | 185 | block128_f block = ctx->block; |
| 178 | void * key = ctx->key; | 186 | void *key = ctx->key; |
| 179 | union { u64 u[2]; u8 c[16]; } scratch; | 187 | union { |
| 180 | 188 | u64 u[2]; | |
| 181 | if (!(flags0&0x40)) | 189 | u8 c[16]; |
| 182 | (*block)(ctx->nonce.c,ctx->cmac.c,key), | 190 | } scratch; |
| 183 | ctx->blocks++; | 191 | |
| 184 | 192 | if (!(flags0 & 0x40)) | |
| 185 | ctx->nonce.c[0] = L = flags0&7; | 193 | (*block)(ctx->nonce.c, ctx->cmac.c, key), |
| 186 | for (n=0,i=15-L;i<15;++i) { | 194 | ctx->blocks++; |
| 195 | |||
| 196 | ctx->nonce.c[0] = L = flags0 & 7; | ||
| 197 | for (n = 0, i = 15 - L; i < 15; ++i) { | ||
| 187 | n |= ctx->nonce.c[i]; | 198 | n |= ctx->nonce.c[i]; |
| 188 | ctx->nonce.c[i]=0; | 199 | ctx->nonce.c[i] = 0; |
| 189 | n <<= 8; | 200 | n <<= 8; |
| 190 | } | 201 | } |
| 191 | n |= ctx->nonce.c[15]; /* reconstructed length */ | 202 | n |= ctx->nonce.c[15]; /* reconstructed length */ |
| 192 | ctx->nonce.c[15]=1; | 203 | ctx->nonce.c[15] = 1; |
| 193 | 204 | ||
| 194 | if (n!=len) return -1; /* length mismatch */ | 205 | if (n != len) |
| 206 | return -1; /* length mismatch */ | ||
| 195 | 207 | ||
| 196 | ctx->blocks += ((len+15)>>3)|1; | 208 | ctx->blocks += ((len + 15) >> 3)|1; |
| 197 | if (ctx->blocks > (U64(1)<<61)) return -2; /* too much data */ | 209 | if (ctx->blocks > (U64(1) << 61)) |
| 210 | return -2; /* too much data */ | ||
| 198 | 211 | ||
| 199 | while (len>=16) { | 212 | while (len >= 16) { |
| 200 | #ifdef __STRICT_ALIGNMENT | 213 | #ifdef __STRICT_ALIGNMENT |
| 201 | union { u64 u[2]; u8 c[16]; } temp; | 214 | union { |
| 215 | u64 u[2]; | ||
| 216 | u8 c[16]; | ||
| 217 | } temp; | ||
| 202 | 218 | ||
| 203 | memcpy (temp.c,inp,16); | 219 | memcpy(temp.c, inp, 16); |
| 204 | ctx->cmac.u[0] ^= temp.u[0]; | 220 | ctx->cmac.u[0] ^= temp.u[0]; |
| 205 | ctx->cmac.u[1] ^= temp.u[1]; | 221 | ctx->cmac.u[1] ^= temp.u[1]; |
| 206 | #else | 222 | #else |
| 207 | ctx->cmac.u[0] ^= ((u64*)inp)[0]; | 223 | ctx->cmac.u[0] ^= ((u64 *)inp)[0]; |
| 208 | ctx->cmac.u[1] ^= ((u64*)inp)[1]; | 224 | ctx->cmac.u[1] ^= ((u64 *)inp)[1]; |
| 209 | #endif | 225 | #endif |
| 210 | (*block)(ctx->cmac.c,ctx->cmac.c,key); | 226 | (*block)(ctx->cmac.c, ctx->cmac.c, key); |
| 211 | (*block)(ctx->nonce.c,scratch.c,key); | 227 | (*block)(ctx->nonce.c, scratch.c, key); |
| 212 | ctr64_inc(ctx->nonce.c); | 228 | ctr64_inc(ctx->nonce.c); |
| 213 | #ifdef __STRICT_ALIGNMENT | 229 | #ifdef __STRICT_ALIGNMENT |
| 214 | temp.u[0] ^= scratch.u[0]; | 230 | temp.u[0] ^= scratch.u[0]; |
| 215 | temp.u[1] ^= scratch.u[1]; | 231 | temp.u[1] ^= scratch.u[1]; |
| 216 | memcpy(out,temp.c,16); | 232 | memcpy(out, temp.c, 16); |
| 217 | #else | 233 | #else |
| 218 | ((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0]; | 234 | ((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]; |
| 219 | ((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1]; | 235 | ((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]; |
| 220 | #endif | 236 | #endif |
| 221 | inp += 16; | 237 | inp += 16; |
| 222 | out += 16; | 238 | out += 16; |
| @@ -224,16 +240,18 @@ int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, | |||
| 224 | } | 240 | } |
| 225 | 241 | ||
| 226 | if (len) { | 242 | if (len) { |
| 227 | for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i]; | 243 | for (i = 0; i < len; ++i) |
| 228 | (*block)(ctx->cmac.c,ctx->cmac.c,key); | 244 | ctx->cmac.c[i] ^= inp[i]; |
| 229 | (*block)(ctx->nonce.c,scratch.c,key); | 245 | (*block)(ctx->cmac.c, ctx->cmac.c, key); |
| 230 | for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i]; | 246 | (*block)(ctx->nonce.c, scratch.c, key); |
| 247 | for (i = 0; i < len; ++i) | ||
| 248 | out[i] = scratch.c[i] ^ inp[i]; | ||
| 231 | } | 249 | } |
| 232 | 250 | ||
| 233 | for (i=15-L;i<16;++i) | 251 | for (i = 15 - L; i < 16; ++i) |
| 234 | ctx->nonce.c[i]=0; | 252 | ctx->nonce.c[i] = 0; |
| 235 | 253 | ||
| 236 | (*block)(ctx->nonce.c,scratch.c,key); | 254 | (*block)(ctx->nonce.c, scratch.c, key); |
| 237 | ctx->cmac.u[0] ^= scratch.u[0]; | 255 | ctx->cmac.u[0] ^= scratch.u[0]; |
| 238 | ctx->cmac.u[1] ^= scratch.u[1]; | 256 | ctx->cmac.u[1] ^= scratch.u[1]; |
| 239 | 257 | ||
| @@ -242,47 +260,57 @@ int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, | |||
| 242 | return 0; | 260 | return 0; |
| 243 | } | 261 | } |
| 244 | 262 | ||
| 245 | int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, | 263 | int |
| 246 | const unsigned char *inp, unsigned char *out, | 264 | CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, |
| 247 | size_t len) | 265 | const unsigned char *inp, unsigned char *out, |
| 266 | size_t len) | ||
| 248 | { | 267 | { |
| 249 | size_t n; | 268 | size_t n; |
| 250 | unsigned int i,L; | 269 | unsigned int i, L; |
| 251 | unsigned char flags0 = ctx->nonce.c[0]; | 270 | unsigned char flags0 = ctx->nonce.c[0]; |
| 252 | block128_f block = ctx->block; | 271 | block128_f block = ctx->block; |
| 253 | void * key = ctx->key; | 272 | void *key = ctx->key; |
| 254 | union { u64 u[2]; u8 c[16]; } scratch; | 273 | union { |
| 255 | 274 | u64 u[2]; | |
| 256 | if (!(flags0&0x40)) | 275 | u8 c[16]; |
| 257 | (*block)(ctx->nonce.c,ctx->cmac.c,key); | 276 | } scratch; |
| 258 | 277 | ||
| 259 | ctx->nonce.c[0] = L = flags0&7; | 278 | if (!(flags0 & 0x40)) |
| 260 | for (n=0,i=15-L;i<15;++i) { | 279 | (*block)(ctx->nonce.c, ctx->cmac.c, key); |
| 280 | |||
| 281 | ctx->nonce.c[0] = L = flags0 & 7; | ||
| 282 | for (n = 0, i = 15 - L; i < 15; ++i) { | ||
| 261 | n |= ctx->nonce.c[i]; | 283 | n |= ctx->nonce.c[i]; |
| 262 | ctx->nonce.c[i]=0; | 284 | ctx->nonce.c[i] = 0; |
| 263 | n <<= 8; | 285 | n <<= 8; |
| 264 | } | 286 | } |
| 265 | n |= ctx->nonce.c[15]; /* reconstructed length */ | 287 | n |= ctx->nonce.c[15]; /* reconstructed length */ |
| 266 | ctx->nonce.c[15]=1; | 288 | ctx->nonce.c[15] = 1; |
| 267 | 289 | ||
| 268 | if (n!=len) return -1; | 290 | if (n != len) |
| 291 | return -1; | ||
| 269 | 292 | ||
| 270 | while (len>=16) { | 293 | while (len >= 16) { |
| 271 | #ifdef __STRICT_ALIGNMENT | 294 | #ifdef __STRICT_ALIGNMENT |
| 272 | union { u64 u[2]; u8 c[16]; } temp; | 295 | union { |
| 296 | u64 u[2]; | ||
| 297 | u8 c[16]; | ||
| 298 | } temp; | ||
| 273 | #endif | 299 | #endif |
| 274 | (*block)(ctx->nonce.c,scratch.c,key); | 300 | (*block)(ctx->nonce.c, scratch.c, key); |
| 275 | ctr64_inc(ctx->nonce.c); | 301 | ctr64_inc(ctx->nonce.c); |
| 276 | #ifdef __STRICT_ALIGNMENT | 302 | #ifdef __STRICT_ALIGNMENT |
| 277 | memcpy (temp.c,inp,16); | 303 | memcpy(temp.c, inp, 16); |
| 278 | ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]); | 304 | ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]); |
| 279 | ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]); | 305 | ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]); |
| 280 | memcpy (out,scratch.c,16); | 306 | memcpy(out, scratch.c, 16); |
| 281 | #else | 307 | #else |
| 282 | ctx->cmac.u[0] ^= (((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0]); | 308 | ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ |
| 283 | ctx->cmac.u[1] ^= (((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1]); | 309 | ((u64 *)inp)[0]); |
| 310 | ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ | ||
| 311 | ((u64 *)inp)[1]); | ||
| 284 | #endif | 312 | #endif |
| 285 | (*block)(ctx->cmac.c,ctx->cmac.c,key); | 313 | (*block)(ctx->cmac.c, ctx->cmac.c, key); |
| 286 | 314 | ||
| 287 | inp += 16; | 315 | inp += 16; |
| 288 | out += 16; | 316 | out += 16; |
| @@ -290,16 +318,16 @@ int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, | |||
| 290 | } | 318 | } |
| 291 | 319 | ||
| 292 | if (len) { | 320 | if (len) { |
| 293 | (*block)(ctx->nonce.c,scratch.c,key); | 321 | (*block)(ctx->nonce.c, scratch.c, key); |
| 294 | for (i=0; i<len; ++i) | 322 | for (i = 0; i < len; ++i) |
| 295 | ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]); | 323 | ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]); |
| 296 | (*block)(ctx->cmac.c,ctx->cmac.c,key); | 324 | (*block)(ctx->cmac.c, ctx->cmac.c, key); |
| 297 | } | 325 | } |
| 298 | 326 | ||
| 299 | for (i=15-L;i<16;++i) | 327 | for (i = 15 - L; i < 16; ++i) |
| 300 | ctx->nonce.c[i]=0; | 328 | ctx->nonce.c[i] = 0; |
| 301 | 329 | ||
| 302 | (*block)(ctx->nonce.c,scratch.c,key); | 330 | (*block)(ctx->nonce.c, scratch.c, key); |
| 303 | ctx->cmac.u[0] ^= scratch.u[0]; | 331 | ctx->cmac.u[0] ^= scratch.u[0]; |
| 304 | ctx->cmac.u[1] ^= scratch.u[1]; | 332 | ctx->cmac.u[1] ^= scratch.u[1]; |
| 305 | 333 | ||
| @@ -308,68 +336,79 @@ int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, | |||
| 308 | return 0; | 336 | return 0; |
| 309 | } | 337 | } |
| 310 | 338 | ||
| 311 | static void ctr64_add (unsigned char *counter,size_t inc) | 339 | static void |
| 312 | { size_t n=8, val=0; | 340 | ctr64_add(unsigned char *counter, size_t inc) |
| 341 | { | ||
| 342 | size_t n = 8, val = 0; | ||
| 313 | 343 | ||
| 314 | counter += 8; | 344 | counter += 8; |
| 315 | do { | 345 | do { |
| 316 | --n; | 346 | --n; |
| 317 | val += counter[n] + (inc&0xff); | 347 | val += counter[n] + (inc & 0xff); |
| 318 | counter[n] = (unsigned char)val; | 348 | counter[n] = (unsigned char)val; |
| 319 | val >>= 8; /* carry bit */ | 349 | val >>= 8; /* carry bit */ |
| 320 | inc >>= 8; | 350 | inc >>= 8; |
| 321 | } while(n && (inc || val)); | 351 | } while (n && (inc || val)); |
| 322 | } | 352 | } |
| 323 | 353 | ||
| 324 | int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, | 354 | int |
| 325 | const unsigned char *inp, unsigned char *out, | 355 | CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, |
| 326 | size_t len,ccm128_f stream) | 356 | const unsigned char *inp, unsigned char *out, |
| 357 | size_t len, ccm128_f stream) | ||
| 327 | { | 358 | { |
| 328 | size_t n; | 359 | size_t n; |
| 329 | unsigned int i,L; | 360 | unsigned int i, L; |
| 330 | unsigned char flags0 = ctx->nonce.c[0]; | 361 | unsigned char flags0 = ctx->nonce.c[0]; |
| 331 | block128_f block = ctx->block; | 362 | block128_f block = ctx->block; |
| 332 | void * key = ctx->key; | 363 | void *key = ctx->key; |
| 333 | union { u64 u[2]; u8 c[16]; } scratch; | 364 | union { |
| 334 | 365 | u64 u[2]; | |
| 335 | if (!(flags0&0x40)) | 366 | u8 c[16]; |
| 336 | (*block)(ctx->nonce.c,ctx->cmac.c,key), | 367 | } scratch; |
| 337 | ctx->blocks++; | 368 | |
| 338 | 369 | if (!(flags0 & 0x40)) | |
| 339 | ctx->nonce.c[0] = L = flags0&7; | 370 | (*block)(ctx->nonce.c, ctx->cmac.c, key), |
| 340 | for (n=0,i=15-L;i<15;++i) { | 371 | ctx->blocks++; |
| 372 | |||
| 373 | ctx->nonce.c[0] = L = flags0 & 7; | ||
| 374 | for (n = 0, i = 15 - L; i < 15; ++i) { | ||
| 341 | n |= ctx->nonce.c[i]; | 375 | n |= ctx->nonce.c[i]; |
| 342 | ctx->nonce.c[i]=0; | 376 | ctx->nonce.c[i] = 0; |
| 343 | n <<= 8; | 377 | n <<= 8; |
| 344 | } | 378 | } |
| 345 | n |= ctx->nonce.c[15]; /* reconstructed length */ | 379 | n |= ctx->nonce.c[15]; /* reconstructed length */ |
| 346 | ctx->nonce.c[15]=1; | 380 | ctx->nonce.c[15] = 1; |
| 347 | 381 | ||
| 348 | if (n!=len) return -1; /* length mismatch */ | 382 | if (n != len) |
| 383 | return -1; /* length mismatch */ | ||
| 349 | 384 | ||
| 350 | ctx->blocks += ((len+15)>>3)|1; | 385 | ctx->blocks += ((len + 15) >> 3)|1; |
| 351 | if (ctx->blocks > (U64(1)<<61)) return -2; /* too much data */ | 386 | if (ctx->blocks > (U64(1) << 61)) |
| 387 | return -2; /* too much data */ | ||
| 352 | 388 | ||
| 353 | if ((n=len/16)) { | 389 | if ((n = len/16)) { |
| 354 | (*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c); | 390 | (*stream)(inp, out, n, key, ctx->nonce.c, ctx->cmac.c); |
| 355 | n *= 16; | 391 | n *= 16; |
| 356 | inp += n; | 392 | inp += n; |
| 357 | out += n; | 393 | out += n; |
| 358 | len -= n; | 394 | len -= n; |
| 359 | if (len) ctr64_add(ctx->nonce.c,n/16); | 395 | if (len) |
| 396 | ctr64_add(ctx->nonce.c, n/16); | ||
| 360 | } | 397 | } |
| 361 | 398 | ||
| 362 | if (len) { | 399 | if (len) { |
| 363 | for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i]; | 400 | for (i = 0; i < len; ++i) |
| 364 | (*block)(ctx->cmac.c,ctx->cmac.c,key); | 401 | ctx->cmac.c[i] ^= inp[i]; |
| 365 | (*block)(ctx->nonce.c,scratch.c,key); | 402 | (*block)(ctx->cmac.c, ctx->cmac.c, key); |
| 366 | for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i]; | 403 | (*block)(ctx->nonce.c, scratch.c, key); |
| 404 | for (i = 0; i < len; ++i) | ||
| 405 | out[i] = scratch.c[i] ^ inp[i]; | ||
| 367 | } | 406 | } |
| 368 | 407 | ||
| 369 | for (i=15-L;i<16;++i) | 408 | for (i = 15 - L; i < 16; ++i) |
| 370 | ctx->nonce.c[i]=0; | 409 | ctx->nonce.c[i] = 0; |
| 371 | 410 | ||
| 372 | (*block)(ctx->nonce.c,scratch.c,key); | 411 | (*block)(ctx->nonce.c, scratch.c, key); |
| 373 | ctx->cmac.u[0] ^= scratch.u[0]; | 412 | ctx->cmac.u[0] ^= scratch.u[0]; |
| 374 | ctx->cmac.u[1] ^= scratch.u[1]; | 413 | ctx->cmac.u[1] ^= scratch.u[1]; |
| 375 | 414 | ||
| @@ -378,51 +417,57 @@ int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, | |||
| 378 | return 0; | 417 | return 0; |
| 379 | } | 418 | } |
| 380 | 419 | ||
| 381 | int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, | 420 | int |
| 382 | const unsigned char *inp, unsigned char *out, | 421 | CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, |
| 383 | size_t len,ccm128_f stream) | 422 | const unsigned char *inp, unsigned char *out, |
| 423 | size_t len, ccm128_f stream) | ||
| 384 | { | 424 | { |
| 385 | size_t n; | 425 | size_t n; |
| 386 | unsigned int i,L; | 426 | unsigned int i, L; |
| 387 | unsigned char flags0 = ctx->nonce.c[0]; | 427 | unsigned char flags0 = ctx->nonce.c[0]; |
| 388 | block128_f block = ctx->block; | 428 | block128_f block = ctx->block; |
| 389 | void * key = ctx->key; | 429 | void *key = ctx->key; |
| 390 | union { u64 u[2]; u8 c[16]; } scratch; | 430 | union { |
| 391 | 431 | u64 u[2]; | |
| 392 | if (!(flags0&0x40)) | 432 | u8 c[16]; |
| 393 | (*block)(ctx->nonce.c,ctx->cmac.c,key); | 433 | } scratch; |
| 394 | 434 | ||
| 395 | ctx->nonce.c[0] = L = flags0&7; | 435 | if (!(flags0 & 0x40)) |
| 396 | for (n=0,i=15-L;i<15;++i) { | 436 | (*block)(ctx->nonce.c, ctx->cmac.c, key); |
| 437 | |||
| 438 | ctx->nonce.c[0] = L = flags0 & 7; | ||
| 439 | for (n = 0, i = 15 - L; i < 15; ++i) { | ||
| 397 | n |= ctx->nonce.c[i]; | 440 | n |= ctx->nonce.c[i]; |
| 398 | ctx->nonce.c[i]=0; | 441 | ctx->nonce.c[i] = 0; |
| 399 | n <<= 8; | 442 | n <<= 8; |
| 400 | } | 443 | } |
| 401 | n |= ctx->nonce.c[15]; /* reconstructed length */ | 444 | n |= ctx->nonce.c[15]; /* reconstructed length */ |
| 402 | ctx->nonce.c[15]=1; | 445 | ctx->nonce.c[15] = 1; |
| 403 | 446 | ||
| 404 | if (n!=len) return -1; | 447 | if (n != len) |
| 448 | return -1; | ||
| 405 | 449 | ||
| 406 | if ((n=len/16)) { | 450 | if ((n = len/16)) { |
| 407 | (*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c); | 451 | (*stream)(inp, out, n, key, ctx->nonce.c, ctx->cmac.c); |
| 408 | n *= 16; | 452 | n *= 16; |
| 409 | inp += n; | 453 | inp += n; |
| 410 | out += n; | 454 | out += n; |
| 411 | len -= n; | 455 | len -= n; |
| 412 | if (len) ctr64_add(ctx->nonce.c,n/16); | 456 | if (len) |
| 457 | ctr64_add(ctx->nonce.c, n/16); | ||
| 413 | } | 458 | } |
| 414 | 459 | ||
| 415 | if (len) { | 460 | if (len) { |
| 416 | (*block)(ctx->nonce.c,scratch.c,key); | 461 | (*block)(ctx->nonce.c, scratch.c, key); |
| 417 | for (i=0; i<len; ++i) | 462 | for (i = 0; i < len; ++i) |
| 418 | ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]); | 463 | ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]); |
| 419 | (*block)(ctx->cmac.c,ctx->cmac.c,key); | 464 | (*block)(ctx->cmac.c, ctx->cmac.c, key); |
| 420 | } | 465 | } |
| 421 | 466 | ||
| 422 | for (i=15-L;i<16;++i) | 467 | for (i = 15 - L; i < 16; ++i) |
| 423 | ctx->nonce.c[i]=0; | 468 | ctx->nonce.c[i] = 0; |
| 424 | 469 | ||
| 425 | (*block)(ctx->nonce.c,scratch.c,key); | 470 | (*block)(ctx->nonce.c, scratch.c, key); |
| 426 | ctx->cmac.u[0] ^= scratch.u[0]; | 471 | ctx->cmac.u[0] ^= scratch.u[0]; |
| 427 | ctx->cmac.u[1] ^= scratch.u[1]; | 472 | ctx->cmac.u[1] ^= scratch.u[1]; |
| 428 | 473 | ||
| @@ -431,11 +476,15 @@ int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, | |||
| 431 | return 0; | 476 | return 0; |
| 432 | } | 477 | } |
| 433 | 478 | ||
| 434 | size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx,unsigned char *tag,size_t len) | 479 | size_t |
| 435 | { unsigned int M = (ctx->nonce.c[0]>>3)&7; /* the M parameter */ | 480 | CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len) |
| 481 | { | ||
| 482 | unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */ | ||
| 436 | 483 | ||
| 437 | M *= 2; M += 2; | 484 | M *= 2; |
| 438 | if (len != M) return 0; | 485 | M += 2; |
| 439 | memcpy(tag,ctx->cmac.c,M); | 486 | if (len != M) |
| 487 | return 0; | ||
| 488 | memcpy(tag, ctx->cmac.c, M); | ||
| 440 | return M; | 489 | return M; |
| 441 | } | 490 | } |
