diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2011-06-03 20:53:00 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2011-06-03 20:53:00 +0000 |
commit | 24d7159abd5e8a3fb5a75167e01b24230fb0874b (patch) | |
tree | 16bdf4ef0a62f645b5954de9a6bc137e38d79c83 /crypto/evp | |
parent | 7978dc989d09061913ce14a23a97c8c5f1821cdb (diff) |
Backport libcrypto audit: check return values of EVP functions instead
of assuming they will always suceed.
Diffstat (limited to 'crypto/evp')
-rw-r--r-- | crypto/evp/bio_md.c | 11 | ||||
-rw-r--r-- | crypto/evp/bio_ok.c | 103 | ||||
-rw-r--r-- | crypto/evp/e_rc2.c | 3 | ||||
-rw-r--r-- | crypto/evp/evp_key.c | 27 | ||||
-rw-r--r-- | crypto/evp/p5_crpt.c | 32 | ||||
-rw-r--r-- | crypto/evp/p5_crpt2.c | 24 | ||||
-rw-r--r-- | crypto/evp/p_open.c | 3 | ||||
-rw-r--r-- | crypto/evp/p_seal.c | 3 | ||||
-rw-r--r-- | crypto/evp/p_sign.c | 6 | ||||
-rw-r--r-- | crypto/evp/p_verify.c | 6 |
10 files changed, 155 insertions, 63 deletions
diff --git a/crypto/evp/bio_md.c b/crypto/evp/bio_md.c index 9841e32e1a..144fdfd56a 100644 --- a/crypto/evp/bio_md.c +++ b/crypto/evp/bio_md.c @@ -153,8 +153,12 @@ static int md_write(BIO *b, const char *in, int inl) { if (ret > 0) { - EVP_DigestUpdate(ctx,(const unsigned char *)in, - (unsigned int)ret); + if (!EVP_DigestUpdate(ctx,(const unsigned char *)in, + (unsigned int)ret)) + { + BIO_clear_retry_flags(b); + return 0; + } } } if(b->next_bio != NULL) @@ -220,7 +224,8 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_DUP: dbio=ptr; dctx=dbio->ptr; - EVP_MD_CTX_copy_ex(dctx,ctx); + if (!EVP_MD_CTX_copy_ex(dctx,ctx)) + return 0; b->init=1; break; default: diff --git a/crypto/evp/bio_ok.c b/crypto/evp/bio_ok.c index 98bc1ab409..e64335353f 100644 --- a/crypto/evp/bio_ok.c +++ b/crypto/evp/bio_ok.c @@ -133,10 +133,10 @@ static int ok_new(BIO *h); static int ok_free(BIO *data); static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); -static void sig_out(BIO* b); -static void sig_in(BIO* b); -static void block_out(BIO* b); -static void block_in(BIO* b); +static int sig_out(BIO* b); +static int sig_in(BIO* b); +static int block_out(BIO* b); +static int block_in(BIO* b); #define OK_BLOCK_SIZE (1024*4) #define OK_BLOCK_BLOCK 4 #define IOBS (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE) @@ -266,10 +266,24 @@ static int ok_read(BIO *b, char *out, int outl) ctx->buf_len+= i; /* no signature yet -- check if we got one */ - if (ctx->sigio == 1) sig_in(b); + if (ctx->sigio == 1) + { + if (!sig_in(b)) + { + BIO_clear_retry_flags(b); + return 0; + } + } /* signature ok -- check if we got block */ - if (ctx->sigio == 0) block_in(b); + if (ctx->sigio == 0) + { + if (!block_in(b)) + { + BIO_clear_retry_flags(b); + return 0; + } + } /* invalid block -- cancel */ if (ctx->cont <= 0) break; @@ -293,7 +307,8 @@ static int ok_write(BIO *b, const char *in, int inl) if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) return(0); - if(ctx->sigio) sig_out(b); + if(ctx->sigio && !sig_out(b)) + return 0; do{ BIO_clear_retry_flags(b); @@ -332,7 +347,11 @@ static int ok_write(BIO *b, const char *in, int inl) if(ctx->buf_len >= OK_BLOCK_SIZE+ OK_BLOCK_BLOCK) { - block_out(b); + if (!block_out(b)) + { + BIO_clear_retry_flags(b); + return 0; + } } }while(inl > 0); @@ -379,7 +398,8 @@ static long ok_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_FLUSH: /* do a final write */ if(ctx->blockout == 0) - block_out(b); + if (!block_out(b)) + return 0; while (ctx->blockout) { @@ -408,7 +428,8 @@ static long ok_ctrl(BIO *b, int cmd, long num, void *ptr) break; case BIO_C_SET_MD: md=ptr; - EVP_DigestInit_ex(&ctx->md, md, NULL); + if (!EVP_DigestInit_ex(&ctx->md, md, NULL)) + return 0; b->init=1; break; case BIO_C_GET_MD: @@ -455,7 +476,7 @@ static void longswap(void *_ptr, size_t len) } } -static void sig_out(BIO* b) +static int sig_out(BIO* b) { BIO_OK_CTX *ctx; EVP_MD_CTX *md; @@ -463,9 +484,10 @@ static void sig_out(BIO* b) ctx=b->ptr; md=&ctx->md; - if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return; + if(ctx->buf_len+ 2* md->digest->md_size > OK_BLOCK_SIZE) return 1; - EVP_DigestInit_ex(md, md->digest, NULL); + if (!EVP_DigestInit_ex(md, md->digest, NULL)) + goto berr; /* FIXME: there's absolutely no guarantee this makes any sense at all, * particularly now EVP_MD_CTX has been restructured. */ @@ -474,14 +496,20 @@ static void sig_out(BIO* b) longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size); ctx->buf_len+= md->digest->md_size; - EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)); - EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL); + if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN))) + goto berr; + if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL)) + goto berr; ctx->buf_len+= md->digest->md_size; ctx->blockout= 1; ctx->sigio= 0; + return 1; + berr: + BIO_clear_retry_flags(b); + return 0; } -static void sig_in(BIO* b) +static int sig_in(BIO* b) { BIO_OK_CTX *ctx; EVP_MD_CTX *md; @@ -491,15 +519,18 @@ static void sig_in(BIO* b) ctx=b->ptr; md=&ctx->md; - if((int)(ctx->buf_len-ctx->buf_off) < 2*md->digest->md_size) return; + if((int)(ctx->buf_len-ctx->buf_off) < 2*md->digest->md_size) return 1; - EVP_DigestInit_ex(md, md->digest, NULL); + if (!EVP_DigestInit_ex(md, md->digest, NULL)) + goto berr; memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size); longswap(md->md_data, md->digest->md_size); ctx->buf_off+= md->digest->md_size; - EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)); - EVP_DigestFinal_ex(md, tmp, NULL); + if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN))) + goto berr; + if (!EVP_DigestFinal_ex(md, tmp, NULL)) + goto berr; ret= memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0; ctx->buf_off+= md->digest->md_size; if(ret == 1) @@ -516,9 +547,13 @@ static void sig_in(BIO* b) { ctx->cont= 0; } + return 1; + berr: + BIO_clear_retry_flags(b); + return 0; } -static void block_out(BIO* b) +static int block_out(BIO* b) { BIO_OK_CTX *ctx; EVP_MD_CTX *md; @@ -532,13 +567,20 @@ static void block_out(BIO* b) ctx->buf[1]=(unsigned char)(tl>>16); ctx->buf[2]=(unsigned char)(tl>>8); ctx->buf[3]=(unsigned char)(tl); - EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl); - EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL); + if (!EVP_DigestUpdate(md, + (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl)) + goto berr; + if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL)) + goto berr; ctx->buf_len+= md->digest->md_size; ctx->blockout= 1; + return 1; + berr: + BIO_clear_retry_flags(b); + return 0; } -static void block_in(BIO* b) +static int block_in(BIO* b) { BIO_OK_CTX *ctx; EVP_MD_CTX *md; @@ -554,10 +596,13 @@ static void block_in(BIO* b) tl|=ctx->buf[2]; tl<<=8; tl|=ctx->buf[3]; - if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return; + if (ctx->buf_len < tl+ OK_BLOCK_BLOCK+ md->digest->md_size) return 1; - EVP_DigestUpdate(md, (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl); - EVP_DigestFinal_ex(md, tmp, NULL); + if (!EVP_DigestUpdate(md, + (unsigned char*) &(ctx->buf[OK_BLOCK_BLOCK]), tl)) + goto berr; + if (!EVP_DigestFinal_ex(md, tmp, NULL)) + goto berr; if(memcmp(&(ctx->buf[tl+ OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == 0) { /* there might be parts from next block lurking around ! */ @@ -571,5 +616,9 @@ static void block_in(BIO* b) { ctx->cont= 0; } + return 1; + berr: + BIO_clear_retry_flags(b); + return 0; } diff --git a/crypto/evp/e_rc2.c b/crypto/evp/e_rc2.c index f78d781129..d4c33b58d4 100644 --- a/crypto/evp/e_rc2.c +++ b/crypto/evp/e_rc2.c @@ -183,7 +183,8 @@ static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) key_bits =rc2_magic_to_meth((int)num); if (!key_bits) return(-1); - if(i > 0) EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1); + if(i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1)) + return -1; EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL); EVP_CIPHER_CTX_set_key_length(c, key_bits / 8); } diff --git a/crypto/evp/evp_key.c b/crypto/evp/evp_key.c index 839d6a3a16..7961fbebf2 100644 --- a/crypto/evp/evp_key.c +++ b/crypto/evp/evp_key.c @@ -120,7 +120,7 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, unsigned char md_buf[EVP_MAX_MD_SIZE]; int niv,nkey,addmd=0; unsigned int mds=0,i; - + int rv = 0; nkey=type->key_len; niv=type->iv_len; OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH); @@ -134,17 +134,24 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, if (!EVP_DigestInit_ex(&c,md, NULL)) return 0; if (addmd++) - EVP_DigestUpdate(&c,&(md_buf[0]),mds); - EVP_DigestUpdate(&c,data,datal); + if (!EVP_DigestUpdate(&c,&(md_buf[0]),mds)) + goto err; + if (!EVP_DigestUpdate(&c,data,datal)) + goto err; if (salt != NULL) - EVP_DigestUpdate(&c,salt,PKCS5_SALT_LEN); - EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds); + if (!EVP_DigestUpdate(&c,salt,PKCS5_SALT_LEN)) + goto err; + if (!EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds)) + goto err; for (i=1; i<(unsigned int)count; i++) { - EVP_DigestInit_ex(&c,md, NULL); - EVP_DigestUpdate(&c,&(md_buf[0]),mds); - EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds); + if (!EVP_DigestInit_ex(&c,md, NULL)) + goto err; + if (!EVP_DigestUpdate(&c,&(md_buf[0]),mds)) + goto err; + if (!EVP_DigestFinal_ex(&c,&(md_buf[0]),&mds)) + goto err; } i=0; if (nkey) @@ -173,8 +180,10 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, } if ((nkey == 0) && (niv == 0)) break; } + rv = type->key_len; + err: EVP_MD_CTX_cleanup(&c); OPENSSL_cleanse(&(md_buf[0]),EVP_MAX_MD_SIZE); - return(type->key_len); + return rv; } diff --git a/crypto/evp/p5_crpt.c b/crypto/evp/p5_crpt.c index 7ecfa8dad9..7d9c1f0123 100644 --- a/crypto/evp/p5_crpt.c +++ b/crypto/evp/p5_crpt.c @@ -82,6 +82,8 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, unsigned char *salt; const unsigned char *pbuf; int mdsize; + int rv = 0; + EVP_MD_CTX_init(&ctx); /* Extract useful info from parameter */ if (param == NULL || param->type != V_ASN1_SEQUENCE || @@ -104,29 +106,37 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, if(!pass) passlen = 0; else if(passlen == -1) passlen = strlen(pass); - EVP_MD_CTX_init(&ctx); - EVP_DigestInit_ex(&ctx, md, NULL); - EVP_DigestUpdate(&ctx, pass, passlen); - EVP_DigestUpdate(&ctx, salt, saltlen); + if (!EVP_DigestInit_ex(&ctx, md, NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, pass, passlen)) + goto err; + if (!EVP_DigestUpdate(&ctx, salt, saltlen)) + goto err; PBEPARAM_free(pbe); - EVP_DigestFinal_ex(&ctx, md_tmp, NULL); + if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL)) + goto err; mdsize = EVP_MD_size(md); if (mdsize < 0) return 0; for (i = 1; i < iter; i++) { - EVP_DigestInit_ex(&ctx, md, NULL); - EVP_DigestUpdate(&ctx, md_tmp, mdsize); - EVP_DigestFinal_ex (&ctx, md_tmp, NULL); + if (!EVP_DigestInit_ex(&ctx, md, NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize)) + goto err; + if (!EVP_DigestFinal_ex (&ctx, md_tmp, NULL)) + goto err; } - EVP_MD_CTX_cleanup(&ctx); OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp)); memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher)); OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16); memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)), EVP_CIPHER_iv_length(cipher)); - EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de); + if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de)) + goto err; OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE); OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); - return 1; + rv = 1; + err: + return rv; } diff --git a/crypto/evp/p5_crpt2.c b/crypto/evp/p5_crpt2.c index 334379f310..01b6b50cf7 100644 --- a/crypto/evp/p5_crpt2.c +++ b/crypto/evp/p5_crpt2.c @@ -110,10 +110,14 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, itmp[1] = (unsigned char)((i >> 16) & 0xff); itmp[2] = (unsigned char)((i >> 8) & 0xff); itmp[3] = (unsigned char)(i & 0xff); - HMAC_Init_ex(&hctx, pass, passlen, digest, NULL); - HMAC_Update(&hctx, salt, saltlen); - HMAC_Update(&hctx, itmp, 4); - HMAC_Final(&hctx, digtmp, NULL); + if (!HMAC_Init_ex(&hctx, pass, passlen, digest, NULL) + || !HMAC_Update(&hctx, salt, saltlen) + || !HMAC_Update(&hctx, itmp, 4) + || !HMAC_Final(&hctx, digtmp, NULL)) + { + HMAC_CTX_cleanup(&hctx); + return 0; + } memcpy(p, digtmp, cplen); for(j = 1; j < iter; j++) { @@ -211,7 +215,11 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, } /* Fixup cipher based on AlgorithmIdentifier */ - EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de); + if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de)) + { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, ERR_R_EVP_LIB); + goto err; + } if(EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) { EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_CIPHER_PARAMETER_ERROR); @@ -278,7 +286,11 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, if(!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd, keylen, key)) goto err; - EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); + if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de)) + { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, ERR_R_EVP_LIB); + goto err; + } OPENSSL_cleanse(key, keylen); PBKDF2PARAM_free(kdf); return 1; diff --git a/crypto/evp/p_open.c b/crypto/evp/p_open.c index 53a59a295c..c748fbea87 100644 --- a/crypto/evp/p_open.c +++ b/crypto/evp/p_open.c @@ -115,7 +115,8 @@ int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) int i; i=EVP_DecryptFinal_ex(ctx,out,outl); - EVP_DecryptInit_ex(ctx,NULL,NULL,NULL,NULL); + if (i) + i = EVP_DecryptInit_ex(ctx,NULL,NULL,NULL,NULL); return(i); } #else /* !OPENSSL_NO_RSA */ diff --git a/crypto/evp/p_seal.c b/crypto/evp/p_seal.c index d8324526e7..e5919b0fbf 100644 --- a/crypto/evp/p_seal.c +++ b/crypto/evp/p_seal.c @@ -110,6 +110,7 @@ int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { int i; i = EVP_EncryptFinal_ex(ctx,out,outl); - EVP_EncryptInit_ex(ctx,NULL,NULL,NULL,NULL); + if (i) + i = EVP_EncryptInit_ex(ctx,NULL,NULL,NULL,NULL); return i; } diff --git a/crypto/evp/p_sign.c b/crypto/evp/p_sign.c index bb893f5bde..ba3596bc09 100644 --- a/crypto/evp/p_sign.c +++ b/crypto/evp/p_sign.c @@ -85,8 +85,10 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, *siglen=0; EVP_MD_CTX_init(&tmp_ctx); - EVP_MD_CTX_copy_ex(&tmp_ctx,ctx); - EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx)) + goto err; + if (!EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len)) + goto err; EVP_MD_CTX_cleanup(&tmp_ctx); if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) diff --git a/crypto/evp/p_verify.c b/crypto/evp/p_verify.c index 41d4b67130..d43f86e823 100644 --- a/crypto/evp/p_verify.c +++ b/crypto/evp/p_verify.c @@ -71,8 +71,10 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, EVP_MD_CTX tmp_ctx; EVP_MD_CTX_init(&tmp_ctx); - EVP_MD_CTX_copy_ex(&tmp_ctx,ctx); - EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx)) + goto err; + if (!EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len)) + goto err; EVP_MD_CTX_cleanup(&tmp_ctx); if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) |