diff options
author | markus <> | 2013-02-14 15:11:44 +0000 |
---|---|---|
committer | markus <> | 2013-02-14 15:11:44 +0000 |
commit | 9822d929c08eed1446dc09464293449326730af2 (patch) | |
tree | cd2035e8f8ac3d4ade1ee779dcaabbe671c2003a /src/lib/libcrypto | |
parent | 692574e51be904b35cfcb2609fd641e93dc8cef7 (diff) | |
download | openbsd-9822d929c08eed1446dc09464293449326730af2.tar.gz openbsd-9822d929c08eed1446dc09464293449326730af2.tar.bz2 openbsd-9822d929c08eed1446dc09464293449326730af2.zip |
cherry pick bugfixes for http://www.openssl.org/news/secadv_20130205.txt
from the openssl git (changes between openssl 1.0.1c and 1.0.1d).
ok djm@
Diffstat (limited to 'src/lib/libcrypto')
-rw-r--r-- | src/lib/libcrypto/asn1/a_verify.c | 6 | ||||
-rw-r--r-- | src/lib/libcrypto/bn/bn_word.c | 25 | ||||
-rw-r--r-- | src/lib/libcrypto/evp/e_aes_cbc_hmac_sha1.c | 216 | ||||
-rw-r--r-- | src/lib/libcrypto/ocsp/ocsp_vfy.c | 9 | ||||
-rw-r--r-- | src/lib/libcrypto/rsa/rsa_oaep.c | 2 |
5 files changed, 216 insertions, 42 deletions
diff --git a/src/lib/libcrypto/asn1/a_verify.c b/src/lib/libcrypto/asn1/a_verify.c index 432722e409..fc84cd3d19 100644 --- a/src/lib/libcrypto/asn1/a_verify.c +++ b/src/lib/libcrypto/asn1/a_verify.c | |||
@@ -140,6 +140,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, | |||
140 | 140 | ||
141 | int mdnid, pknid; | 141 | int mdnid, pknid; |
142 | 142 | ||
143 | if (!pkey) | ||
144 | { | ||
145 | ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); | ||
146 | return -1; | ||
147 | } | ||
148 | |||
143 | EVP_MD_CTX_init(&ctx); | 149 | EVP_MD_CTX_init(&ctx); |
144 | 150 | ||
145 | /* Convert signature OID into digest and public key OIDs */ | 151 | /* Convert signature OID into digest and public key OIDs */ |
diff --git a/src/lib/libcrypto/bn/bn_word.c b/src/lib/libcrypto/bn/bn_word.c index ee7b87c45c..de83a15b99 100644 --- a/src/lib/libcrypto/bn/bn_word.c +++ b/src/lib/libcrypto/bn/bn_word.c | |||
@@ -144,26 +144,17 @@ int BN_add_word(BIGNUM *a, BN_ULONG w) | |||
144 | a->neg=!(a->neg); | 144 | a->neg=!(a->neg); |
145 | return(i); | 145 | return(i); |
146 | } | 146 | } |
147 | /* Only expand (and risk failing) if it's possibly necessary */ | 147 | for (i=0;w!=0 && i<a->top;i++) |
148 | if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) && | ||
149 | (bn_wexpand(a,a->top+1) == NULL)) | ||
150 | return(0); | ||
151 | i=0; | ||
152 | for (;;) | ||
153 | { | 148 | { |
154 | if (i >= a->top) | 149 | a->d[i] = l = (a->d[i]+w)&BN_MASK2; |
155 | l=w; | 150 | w = (w>l)?1:0; |
156 | else | ||
157 | l=(a->d[i]+w)&BN_MASK2; | ||
158 | a->d[i]=l; | ||
159 | if (w > l) | ||
160 | w=1; | ||
161 | else | ||
162 | break; | ||
163 | i++; | ||
164 | } | 151 | } |
165 | if (i >= a->top) | 152 | if (w && i==a->top) |
153 | { | ||
154 | if (bn_wexpand(a,a->top+1) == NULL) return 0; | ||
166 | a->top++; | 155 | a->top++; |
156 | a->d[i]=w; | ||
157 | } | ||
167 | bn_check_top(a); | 158 | bn_check_top(a); |
168 | return(1); | 159 | return(1); |
169 | } | 160 | } |
diff --git a/src/lib/libcrypto/evp/e_aes_cbc_hmac_sha1.c b/src/lib/libcrypto/evp/e_aes_cbc_hmac_sha1.c index 710fb79baf..483e04b605 100644 --- a/src/lib/libcrypto/evp/e_aes_cbc_hmac_sha1.c +++ b/src/lib/libcrypto/evp/e_aes_cbc_hmac_sha1.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* ==================================================================== | 1 | /* ==================================================================== |
2 | * Copyright (c) 2011 The OpenSSL Project. All rights reserved. | 2 | * Copyright (c) 2011-2013 The OpenSSL Project. All rights reserved. |
3 | * | 3 | * |
4 | * Redistribution and use in source and binary forms, with or without | 4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions | 5 | * modification, are permitted provided that the following conditions |
@@ -90,6 +90,10 @@ typedef struct | |||
90 | defined(_M_AMD64) || defined(_M_X64) || \ | 90 | defined(_M_AMD64) || defined(_M_X64) || \ |
91 | defined(__INTEL__) ) | 91 | defined(__INTEL__) ) |
92 | 92 | ||
93 | #if defined(__GNUC__) && __GNUC__>=2 && !defined(PEDANTIC) | ||
94 | # define BSWAP(x) ({ unsigned int r=(x); asm ("bswapl %0":"=r"(r):"0"(r)); r; }) | ||
95 | #endif | ||
96 | |||
93 | extern unsigned int OPENSSL_ia32cap_P[2]; | 97 | extern unsigned int OPENSSL_ia32cap_P[2]; |
94 | #define AESNI_CAPABLE (1<<(57-32)) | 98 | #define AESNI_CAPABLE (1<<(57-32)) |
95 | 99 | ||
@@ -167,6 +171,9 @@ static void sha1_update(SHA_CTX *c,const void *data,size_t len) | |||
167 | SHA1_Update(c,ptr,res); | 171 | SHA1_Update(c,ptr,res); |
168 | } | 172 | } |
169 | 173 | ||
174 | #ifdef SHA1_Update | ||
175 | #undef SHA1_Update | ||
176 | #endif | ||
170 | #define SHA1_Update sha1_update | 177 | #define SHA1_Update sha1_update |
171 | 178 | ||
172 | static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | 179 | static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, |
@@ -184,6 +191,8 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |||
184 | sha_off = SHA_CBLOCK-key->md.num; | 191 | sha_off = SHA_CBLOCK-key->md.num; |
185 | #endif | 192 | #endif |
186 | 193 | ||
194 | key->payload_length = NO_PAYLOAD_LENGTH; | ||
195 | |||
187 | if (len%AES_BLOCK_SIZE) return 0; | 196 | if (len%AES_BLOCK_SIZE) return 0; |
188 | 197 | ||
189 | if (ctx->encrypt) { | 198 | if (ctx->encrypt) { |
@@ -234,47 +243,210 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |||
234 | &key->ks,ctx->iv,1); | 243 | &key->ks,ctx->iv,1); |
235 | } | 244 | } |
236 | } else { | 245 | } else { |
237 | unsigned char mac[SHA_DIGEST_LENGTH]; | 246 | union { unsigned int u[SHA_DIGEST_LENGTH/sizeof(unsigned int)]; |
247 | unsigned char c[32+SHA_DIGEST_LENGTH]; } mac, *pmac; | ||
248 | |||
249 | /* arrange cache line alignment */ | ||
250 | pmac = (void *)(((size_t)mac.c+31)&((size_t)0-32)); | ||
238 | 251 | ||
239 | /* decrypt HMAC|padding at once */ | 252 | /* decrypt HMAC|padding at once */ |
240 | aesni_cbc_encrypt(in,out,len, | 253 | aesni_cbc_encrypt(in,out,len, |
241 | &key->ks,ctx->iv,0); | 254 | &key->ks,ctx->iv,0); |
242 | 255 | ||
243 | if (plen) { /* "TLS" mode of operation */ | 256 | if (plen) { /* "TLS" mode of operation */ |
244 | /* figure out payload length */ | 257 | size_t inp_len, mask, j, i; |
245 | if (len<(size_t)(out[len-1]+1+SHA_DIGEST_LENGTH)) | 258 | unsigned int res, maxpad, pad, bitlen; |
246 | return 0; | 259 | int ret = 1; |
247 | 260 | union { unsigned int u[SHA_LBLOCK]; | |
248 | len -= (out[len-1]+1+SHA_DIGEST_LENGTH); | 261 | unsigned char c[SHA_CBLOCK]; } |
262 | *data = (void *)key->md.data; | ||
249 | 263 | ||
250 | if ((key->aux.tls_aad[plen-4]<<8|key->aux.tls_aad[plen-3]) | 264 | if ((key->aux.tls_aad[plen-4]<<8|key->aux.tls_aad[plen-3]) |
251 | >= TLS1_1_VERSION) { | 265 | >= TLS1_1_VERSION) |
252 | len -= AES_BLOCK_SIZE; | ||
253 | iv = AES_BLOCK_SIZE; | 266 | iv = AES_BLOCK_SIZE; |
254 | } | ||
255 | 267 | ||
256 | key->aux.tls_aad[plen-2] = len>>8; | 268 | if (len<(iv+SHA_DIGEST_LENGTH+1)) |
257 | key->aux.tls_aad[plen-1] = len; | 269 | return 0; |
270 | |||
271 | /* omit explicit iv */ | ||
272 | out += iv; | ||
273 | len -= iv; | ||
274 | |||
275 | /* figure out payload length */ | ||
276 | pad = out[len-1]; | ||
277 | maxpad = len-(SHA_DIGEST_LENGTH+1); | ||
278 | maxpad |= (255-maxpad)>>(sizeof(maxpad)*8-8); | ||
279 | maxpad &= 255; | ||
280 | |||
281 | inp_len = len - (SHA_DIGEST_LENGTH+pad+1); | ||
282 | mask = (0-((inp_len-len)>>(sizeof(inp_len)*8-1))); | ||
283 | inp_len &= mask; | ||
284 | ret &= (int)mask; | ||
285 | |||
286 | key->aux.tls_aad[plen-2] = inp_len>>8; | ||
287 | key->aux.tls_aad[plen-1] = inp_len; | ||
258 | 288 | ||
259 | /* calculate HMAC and verify it */ | 289 | /* calculate HMAC */ |
260 | key->md = key->head; | 290 | key->md = key->head; |
261 | SHA1_Update(&key->md,key->aux.tls_aad,plen); | 291 | SHA1_Update(&key->md,key->aux.tls_aad,plen); |
262 | SHA1_Update(&key->md,out+iv,len); | ||
263 | SHA1_Final(mac,&key->md); | ||
264 | 292 | ||
293 | #if 1 | ||
294 | len -= SHA_DIGEST_LENGTH; /* amend mac */ | ||
295 | if (len>=(256+SHA_CBLOCK)) { | ||
296 | j = (len-(256+SHA_CBLOCK))&(0-SHA_CBLOCK); | ||
297 | j += SHA_CBLOCK-key->md.num; | ||
298 | SHA1_Update(&key->md,out,j); | ||
299 | out += j; | ||
300 | len -= j; | ||
301 | inp_len -= j; | ||
302 | } | ||
303 | |||
304 | /* but pretend as if we hashed padded payload */ | ||
305 | bitlen = key->md.Nl+(inp_len<<3); /* at most 18 bits */ | ||
306 | #ifdef BSWAP | ||
307 | bitlen = BSWAP(bitlen); | ||
308 | #else | ||
309 | mac.c[0] = 0; | ||
310 | mac.c[1] = (unsigned char)(bitlen>>16); | ||
311 | mac.c[2] = (unsigned char)(bitlen>>8); | ||
312 | mac.c[3] = (unsigned char)bitlen; | ||
313 | bitlen = mac.u[0]; | ||
314 | #endif | ||
315 | |||
316 | pmac->u[0]=0; | ||
317 | pmac->u[1]=0; | ||
318 | pmac->u[2]=0; | ||
319 | pmac->u[3]=0; | ||
320 | pmac->u[4]=0; | ||
321 | |||
322 | for (res=key->md.num, j=0;j<len;j++) { | ||
323 | size_t c = out[j]; | ||
324 | mask = (j-inp_len)>>(sizeof(j)*8-8); | ||
325 | c &= mask; | ||
326 | c |= 0x80&~mask&~((inp_len-j)>>(sizeof(j)*8-8)); | ||
327 | data->c[res++]=(unsigned char)c; | ||
328 | |||
329 | if (res!=SHA_CBLOCK) continue; | ||
330 | |||
331 | mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1)); | ||
332 | data->u[SHA_LBLOCK-1] |= bitlen&mask; | ||
333 | sha1_block_data_order(&key->md,data,1); | ||
334 | mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1)); | ||
335 | pmac->u[0] |= key->md.h0 & mask; | ||
336 | pmac->u[1] |= key->md.h1 & mask; | ||
337 | pmac->u[2] |= key->md.h2 & mask; | ||
338 | pmac->u[3] |= key->md.h3 & mask; | ||
339 | pmac->u[4] |= key->md.h4 & mask; | ||
340 | res=0; | ||
341 | } | ||
342 | |||
343 | for(i=res;i<SHA_CBLOCK;i++,j++) data->c[i]=0; | ||
344 | |||
345 | if (res>SHA_CBLOCK-8) { | ||
346 | mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1)); | ||
347 | data->u[SHA_LBLOCK-1] |= bitlen&mask; | ||
348 | sha1_block_data_order(&key->md,data,1); | ||
349 | mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1)); | ||
350 | pmac->u[0] |= key->md.h0 & mask; | ||
351 | pmac->u[1] |= key->md.h1 & mask; | ||
352 | pmac->u[2] |= key->md.h2 & mask; | ||
353 | pmac->u[3] |= key->md.h3 & mask; | ||
354 | pmac->u[4] |= key->md.h4 & mask; | ||
355 | |||
356 | memset(data,0,SHA_CBLOCK); | ||
357 | j+=64; | ||
358 | } | ||
359 | data->u[SHA_LBLOCK-1] = bitlen; | ||
360 | sha1_block_data_order(&key->md,data,1); | ||
361 | mask = 0-((j-inp_len-73)>>(sizeof(j)*8-1)); | ||
362 | pmac->u[0] |= key->md.h0 & mask; | ||
363 | pmac->u[1] |= key->md.h1 & mask; | ||
364 | pmac->u[2] |= key->md.h2 & mask; | ||
365 | pmac->u[3] |= key->md.h3 & mask; | ||
366 | pmac->u[4] |= key->md.h4 & mask; | ||
367 | |||
368 | #ifdef BSWAP | ||
369 | pmac->u[0] = BSWAP(pmac->u[0]); | ||
370 | pmac->u[1] = BSWAP(pmac->u[1]); | ||
371 | pmac->u[2] = BSWAP(pmac->u[2]); | ||
372 | pmac->u[3] = BSWAP(pmac->u[3]); | ||
373 | pmac->u[4] = BSWAP(pmac->u[4]); | ||
374 | #else | ||
375 | for (i=0;i<5;i++) { | ||
376 | res = pmac->u[i]; | ||
377 | pmac->c[4*i+0]=(unsigned char)(res>>24); | ||
378 | pmac->c[4*i+1]=(unsigned char)(res>>16); | ||
379 | pmac->c[4*i+2]=(unsigned char)(res>>8); | ||
380 | pmac->c[4*i+3]=(unsigned char)res; | ||
381 | } | ||
382 | #endif | ||
383 | len += SHA_DIGEST_LENGTH; | ||
384 | #else | ||
385 | SHA1_Update(&key->md,out,inp_len); | ||
386 | res = key->md.num; | ||
387 | SHA1_Final(pmac->c,&key->md); | ||
388 | |||
389 | { | ||
390 | unsigned int inp_blocks, pad_blocks; | ||
391 | |||
392 | /* but pretend as if we hashed padded payload */ | ||
393 | inp_blocks = 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1)); | ||
394 | res += (unsigned int)(len-inp_len); | ||
395 | pad_blocks = res / SHA_CBLOCK; | ||
396 | res %= SHA_CBLOCK; | ||
397 | pad_blocks += 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1)); | ||
398 | for (;inp_blocks<pad_blocks;inp_blocks++) | ||
399 | sha1_block_data_order(&key->md,data,1); | ||
400 | } | ||
401 | #endif | ||
265 | key->md = key->tail; | 402 | key->md = key->tail; |
266 | SHA1_Update(&key->md,mac,SHA_DIGEST_LENGTH); | 403 | SHA1_Update(&key->md,pmac->c,SHA_DIGEST_LENGTH); |
267 | SHA1_Final(mac,&key->md); | 404 | SHA1_Final(pmac->c,&key->md); |
268 | 405 | ||
269 | if (memcmp(out+iv+len,mac,SHA_DIGEST_LENGTH)) | 406 | /* verify HMAC */ |
270 | return 0; | 407 | out += inp_len; |
408 | len -= inp_len; | ||
409 | #if 1 | ||
410 | { | ||
411 | unsigned char *p = out+len-1-maxpad-SHA_DIGEST_LENGTH; | ||
412 | size_t off = out-p; | ||
413 | unsigned int c, cmask; | ||
414 | |||
415 | maxpad += SHA_DIGEST_LENGTH; | ||
416 | for (res=0,i=0,j=0;j<maxpad;j++) { | ||
417 | c = p[j]; | ||
418 | cmask = ((int)(j-off-SHA_DIGEST_LENGTH))>>(sizeof(int)*8-1); | ||
419 | res |= (c^pad)&~cmask; /* ... and padding */ | ||
420 | cmask &= ((int)(off-1-j))>>(sizeof(int)*8-1); | ||
421 | res |= (c^pmac->c[i])&cmask; | ||
422 | i += 1&cmask; | ||
423 | } | ||
424 | maxpad -= SHA_DIGEST_LENGTH; | ||
425 | |||
426 | res = 0-((0-res)>>(sizeof(res)*8-1)); | ||
427 | ret &= (int)~res; | ||
428 | } | ||
429 | #else | ||
430 | for (res=0,i=0;i<SHA_DIGEST_LENGTH;i++) | ||
431 | res |= out[i]^pmac->c[i]; | ||
432 | res = 0-((0-res)>>(sizeof(res)*8-1)); | ||
433 | ret &= (int)~res; | ||
434 | |||
435 | /* verify padding */ | ||
436 | pad = (pad&~res) | (maxpad&res); | ||
437 | out = out+len-1-pad; | ||
438 | for (res=0,i=0;i<pad;i++) | ||
439 | res |= out[i]^pad; | ||
440 | |||
441 | res = (0-res)>>(sizeof(res)*8-1); | ||
442 | ret &= (int)~res; | ||
443 | #endif | ||
444 | return ret; | ||
271 | } else { | 445 | } else { |
272 | SHA1_Update(&key->md,out,len); | 446 | SHA1_Update(&key->md,out,len); |
273 | } | 447 | } |
274 | } | 448 | } |
275 | 449 | ||
276 | key->payload_length = NO_PAYLOAD_LENGTH; | ||
277 | |||
278 | return 1; | 450 | return 1; |
279 | } | 451 | } |
280 | 452 | ||
@@ -309,6 +481,8 @@ static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void | |||
309 | SHA1_Init(&key->tail); | 481 | SHA1_Init(&key->tail); |
310 | SHA1_Update(&key->tail,hmac_key,sizeof(hmac_key)); | 482 | SHA1_Update(&key->tail,hmac_key,sizeof(hmac_key)); |
311 | 483 | ||
484 | OPENSSL_cleanse(hmac_key,sizeof(hmac_key)); | ||
485 | |||
312 | return 1; | 486 | return 1; |
313 | } | 487 | } |
314 | case EVP_CTRL_AEAD_TLS1_AAD: | 488 | case EVP_CTRL_AEAD_TLS1_AAD: |
diff --git a/src/lib/libcrypto/ocsp/ocsp_vfy.c b/src/lib/libcrypto/ocsp/ocsp_vfy.c index 415d67e61c..91a45c9133 100644 --- a/src/lib/libcrypto/ocsp/ocsp_vfy.c +++ b/src/lib/libcrypto/ocsp/ocsp_vfy.c | |||
@@ -91,9 +91,12 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, | |||
91 | { | 91 | { |
92 | EVP_PKEY *skey; | 92 | EVP_PKEY *skey; |
93 | skey = X509_get_pubkey(signer); | 93 | skey = X509_get_pubkey(signer); |
94 | ret = OCSP_BASICRESP_verify(bs, skey, 0); | 94 | if (skey) |
95 | EVP_PKEY_free(skey); | 95 | { |
96 | if(ret <= 0) | 96 | ret = OCSP_BASICRESP_verify(bs, skey, 0); |
97 | EVP_PKEY_free(skey); | ||
98 | } | ||
99 | if(!skey || ret <= 0) | ||
97 | { | 100 | { |
98 | OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); | 101 | OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); |
99 | goto end; | 102 | goto end; |
diff --git a/src/lib/libcrypto/rsa/rsa_oaep.c b/src/lib/libcrypto/rsa/rsa_oaep.c index 553d212ebe..e08ac151ff 100644 --- a/src/lib/libcrypto/rsa/rsa_oaep.c +++ b/src/lib/libcrypto/rsa/rsa_oaep.c | |||
@@ -149,7 +149,7 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, | |||
149 | if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL)) | 149 | if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL)) |
150 | return -1; | 150 | return -1; |
151 | 151 | ||
152 | if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad) | 152 | if (timingsafe_bcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad) |
153 | goto decoding_err; | 153 | goto decoding_err; |
154 | else | 154 | else |
155 | { | 155 | { |