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 | } |