diff -Nru openssl098-0.9.8o/debian/changelog openssl098-0.9.8o/debian/changelog --- openssl098-0.9.8o/debian/changelog 2012-04-24 17:07:07.000000000 +0200 +++ openssl098-0.9.8o/debian/changelog 2014-06-23 10:50:12.000000000 +0200 @@ -1,3 +1,48 @@ +openssl098 (0.9.8o-7ubuntu3.2) precise-security; urgency=medium + + * SECURITY UPDATE: regression with certain renegotiations (LP: #1332643) + - debian/patches/CVE-2014-0224-regression2.patch: accept CCS after + sending finished ssl/s3_clnt.c. + * Bring up to date with latest security patches from Ubuntu 10.04: + (LP: #1331452) + * SECURITY UPDATE: MITM via change cipher spec + - debian/patches/CVE-2014-0224-1.patch: only accept change cipher spec + when it is expected in ssl/s3_clnt.c, ssl/s3_pkt.c, ssl/s3_srvr.c, + ssl/ssl3.h. + - debian/patches/CVE-2014-0224-2.patch: don't accept zero length master + secrets in ssl/s3_pkt.c. + - debian/patches/CVE-2014-0224-3.patch: allow CCS after resumption in + ssl/s3_clnt.c. + - CVE-2014-0224 + * SECURITY UPDATE: denial of service via DTLS recursion flaw + - debian/patches/CVE-2014-0221.patch: handle DTLS hello request without + recursion in ssl/d1_both.c. + - CVE-2014-0221 + * SECURITY UPDATE: arbitrary code execution via DTLS invalid fragment + - debian/patches/CVE-2014-0195.patch: add consistency check for DTLS + fragments in ssl/d1_both.c. + - CVE-2014-0195 + * SECURITY UPDATE: "Lucky Thirteen" timing side-channel TLS attack + - debian/patches/CVE-2013-0169.patch: massive code changes + - CVE-2013-0169 + * SECURITY UPDATE: denial of service via invalid OCSP key + - debian/patches/CVE-2013-0166.patch: properly handle NULL key in + crypto/asn1/a_verify.c, crypto/ocsp/ocsp_vfy.c. + - CVE-2013-0166 + * SECURITY UPDATE: denial of service attack in DTLS implementation + - debian/patches/CVE_2012-2333.patch: guard for integer overflow + before skipping explicit IV + - CVE-2012-2333 + * SECURITY UPDATE: million message attack (MMA) in CMS and PKCS #7 + - debian/patches/CVE-2012-0884.patch: use a random key if RSA + decryption fails to avoid leaking timing information + - CVE-2012-0884 + * debian/patches/CVE-2012-0884-extra.patch: detect symmetric crypto + - errors in PKCS7_decrypt and initialize tkeylen properly when + encrypting CMS messages. + + -- Louis Bouchard Wed, 18 Jun 2014 12:22:48 +0200 + openssl098 (0.9.8o-7ubuntu3.1) precise-security; urgency=low * Bring up to date with latest security patches from Ubuntu 11.04: diff -Nru openssl098-0.9.8o/debian/patches/CVE-2012-0884-extra.patch openssl098-0.9.8o/debian/patches/CVE-2012-0884-extra.patch --- openssl098-0.9.8o/debian/patches/CVE-2012-0884-extra.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssl098-0.9.8o/debian/patches/CVE-2012-0884-extra.patch 2014-06-19 09:49:57.000000000 +0200 @@ -0,0 +1,74 @@ +Origin: http://cvs.openssl.org/chngview?cn=22161 + and http://cvs.openssl.org/chngview?cn=22537 +Subject: Detect symmetric crypto errors in PKCS7_decrypt and initialise + tkeylen properly + + Thanks to Ivan Nestlerode for reporting + this bug. + + Initialise tkeylen properly when encrypting CMS messages. + Thanks to Solar Designer of Openwall for reporting this issue. + [Steve Henson] + +Index: openssl098-0.9.8o/crypto/cms/cms_enc.c +=================================================================== +--- openssl098-0.9.8o.orig/crypto/cms/cms_enc.c 2014-06-18 11:47:49.604252737 +0200 ++++ openssl098-0.9.8o/crypto/cms/cms_enc.c 2014-06-18 11:51:40.848258658 +0200 +@@ -139,10 +139,10 @@ + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } ++ tkeylen = EVP_CIPHER_CTX_key_length(ctx); + /* Generate random session key */ + if (!enc || !ec->key) + { +- tkeylen = EVP_CIPHER_CTX_key_length(ctx); + tkey = OPENSSL_malloc(tkeylen); + if (!tkey) + { +@@ -174,7 +174,7 @@ + /* Only reveal failure if debugging so we don't + * leak information which may be useful in MMA. + */ +- if (ec->debug) ++ if (enc || ec->debug) + { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_INVALID_KEY_LENGTH); +Index: openssl098-0.9.8o/crypto/pkcs7/pk7_smime.c +=================================================================== +--- openssl098-0.9.8o.orig/crypto/pkcs7/pk7_smime.c 2009-03-15 14:36:01.000000000 +0100 ++++ openssl098-0.9.8o/crypto/pkcs7/pk7_smime.c 2014-06-18 11:51:40.844258658 +0200 +@@ -486,15 +486,30 @@ + return 0; + } + ret = SMIME_text(bread, data); ++ if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) ++ { ++ if (!BIO_get_cipher_status(tmpmem)) ++ ret = 0; ++ } + BIO_free_all(bread); + return ret; + } else { + for(;;) { + i = BIO_read(tmpmem, buf, sizeof(buf)); +- if(i <= 0) break; ++ if(i <= 0) ++ { ++ ret = 1; ++ if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) ++ { ++ if (!BIO_get_cipher_status(tmpmem)) ++ ret = 0; ++ } ++ ++ break; ++ } + BIO_write(data, buf, i); + } + BIO_free_all(tmpmem); +- return 1; ++ return ret; + } + } diff -Nru openssl098-0.9.8o/debian/patches/CVE-2012-0884.patch openssl098-0.9.8o/debian/patches/CVE-2012-0884.patch --- openssl098-0.9.8o/debian/patches/CVE-2012-0884.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssl098-0.9.8o/debian/patches/CVE-2012-0884.patch 2014-06-20 09:54:24.000000000 +0200 @@ -0,0 +1,402 @@ +Origin: http://cvs.openssl.org/chngview?cn=22238 +Subject: If RSA decryption fails use a random key and continue with + symmetric decryption process to avoid leaking timing information + to an attacker. + + *) Fix MMA (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) weakness + in CMS and PKCS7 code. When RSA decryption fails use a random key for + content decryption and always return the same error. Note: this attack + needs on average 2^20 messages so it only affects automated senders. The + old behaviour can be reenabled in the CMS code by setting the + CMS_DEBUG_DECRYPT flag: this is useful for debugging and testing where + an MMA defence is not necessary. + Thanks to Ivan Nestlerode for discovering + this issue. (CVE-2012-0884) + [Steve Henson] + +(Ubuntu note: also includes http://cvs.openssl.org/chngview?cn=22564 + to fix compilation warning -- sbeattie) + +--- + apps/cms.c | 4 ++ + crypto/cms/cms.h | 1 + crypto/cms/cms_enc.c | 60 ++++++++++++++++++++++++++++++--------- + crypto/cms/cms_env.c | 12 ++++++- + crypto/cms/cms_lcl.h | 2 + + crypto/cms/cms_smime.c | 37 +++++++++++++++++++++--- + crypto/pkcs7/pk7_doit.c | 73 ++++++++++++++++++++++++++++++++++-------------- + 7 files changed, 149 insertions(+), 40 deletions(-) + +Index: b/apps/cms.c +=================================================================== +--- a/apps/cms.c ++++ b/apps/cms.c +@@ -226,6 +226,8 @@ int MAIN(int argc, char **argv) + else if (!strcmp(*args,"-camellia256")) + cipher = EVP_camellia_256_cbc(); + #endif ++ else if (!strcmp (*args, "-debug_decrypt")) ++ flags |= CMS_DEBUG_DECRYPT; + else if (!strcmp (*args, "-text")) + flags |= CMS_TEXT; + else if (!strcmp (*args, "-nointern")) +@@ -1013,6 +1015,8 @@ int MAIN(int argc, char **argv) + ret = 4; + if (operation == SMIME_DECRYPT) + { ++ if (flags & CMS_DEBUG_DECRYPT) ++ CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags); + + if (secret_key) + { +Index: b/crypto/cms/cms.h +=================================================================== +--- a/crypto/cms/cms.h ++++ b/crypto/cms/cms.h +@@ -110,6 +110,7 @@ DECLARE_ASN1_FUNCTIONS_const(CMS_Receipt + #define CMS_PARTIAL 0x4000 + #define CMS_REUSE_DIGEST 0x8000 + #define CMS_USE_KEYID 0x10000 ++#define CMS_DEBUG_DECRYPT 0x20000 + + const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms); + +Index: b/crypto/cms/cms_enc.c +=================================================================== +--- a/crypto/cms/cms_enc.c ++++ b/crypto/cms/cms_enc.c +@@ -73,6 +73,8 @@ BIO *cms_EncryptedContent_init_bio(CMS_E + const EVP_CIPHER *ciph; + X509_ALGOR *calg = ec->contentEncryptionAlgorithm; + unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; ++ unsigned char *tkey = NULL; ++ size_t tkeylen = 0; + + int ok = 0; + +@@ -137,32 +139,57 @@ BIO *cms_EncryptedContent_init_bio(CMS_E + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } +- +- +- if (enc && !ec->key) ++ /* Generate random session key */ ++ if (!enc || !ec->key) + { +- /* Generate random key */ +- if (!ec->keylen) +- ec->keylen = EVP_CIPHER_CTX_key_length(ctx); +- ec->key = OPENSSL_malloc(ec->keylen); +- if (!ec->key) ++ tkeylen = EVP_CIPHER_CTX_key_length(ctx); ++ tkey = OPENSSL_malloc(tkeylen); ++ if (!tkey) + { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + ERR_R_MALLOC_FAILURE); + goto err; + } +- if (EVP_CIPHER_CTX_rand_key(ctx, ec->key) <= 0) ++ if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) + goto err; +- keep_key = 1; + } +- else if (ec->keylen != (unsigned int)EVP_CIPHER_CTX_key_length(ctx)) ++ ++ if (!ec->key) ++ { ++ ec->key = tkey; ++ ec->keylen = tkeylen; ++ tkey = NULL; ++ if (enc) ++ keep_key = 1; ++ else ++ ERR_clear_error(); ++ ++ } ++ ++ if (ec->keylen != tkeylen) + { + /* If necessary set key length */ + if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) + { +- CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, +- CMS_R_INVALID_KEY_LENGTH); +- goto err; ++ /* Only reveal failure if debugging so we don't ++ * leak information which may be useful in MMA. ++ */ ++ if (ec->debug) ++ { ++ CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ++ CMS_R_INVALID_KEY_LENGTH); ++ goto err; ++ } ++ else ++ { ++ /* Use random key */ ++ OPENSSL_cleanse(ec->key, ec->keylen); ++ OPENSSL_free(ec->key); ++ ec->key = tkey; ++ ec->keylen = tkeylen; ++ tkey = NULL; ++ ERR_clear_error(); ++ } + } + } + +@@ -198,6 +225,11 @@ BIO *cms_EncryptedContent_init_bio(CMS_E + OPENSSL_free(ec->key); + ec->key = NULL; + } ++ if (tkey) ++ { ++ OPENSSL_cleanse(tkey, tkeylen); ++ OPENSSL_free(tkey); ++ } + if (ok) + return b; + BIO_free(b); +Index: b/crypto/cms/cms_env.c +=================================================================== +--- a/crypto/cms/cms_env.c ++++ b/crypto/cms/cms_env.c +@@ -352,6 +352,8 @@ static int cms_RecipientInfo_ktri_decryp + unsigned char *ek = NULL; + int eklen; + int ret = 0; ++ CMS_EncryptedContentInfo *ec; ++ ec = cms->d.envelopedData->encryptedContentInfo; + + if (ktri->pkey == NULL) + { +@@ -382,8 +384,14 @@ static int cms_RecipientInfo_ktri_decryp + + ret = 1; + +- cms->d.envelopedData->encryptedContentInfo->key = ek; +- cms->d.envelopedData->encryptedContentInfo->keylen = eklen; ++ if (ec->key) ++ { ++ OPENSSL_cleanse(ec->key, ec->keylen); ++ OPENSSL_free(ec->key); ++ } ++ ++ ec->key = ek; ++ ec->keylen = eklen; + + err: + if (!ret && ek) +Index: b/crypto/cms/cms_lcl.h +=================================================================== +--- a/crypto/cms/cms_lcl.h ++++ b/crypto/cms/cms_lcl.h +@@ -175,6 +175,8 @@ struct CMS_EncryptedContentInfo_st + const EVP_CIPHER *cipher; + unsigned char *key; + size_t keylen; ++ /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */ ++ int debug; + }; + + struct CMS_RecipientInfo_st +Index: b/crypto/cms/cms_smime.c +=================================================================== +--- a/crypto/cms/cms_smime.c ++++ b/crypto/cms/cms_smime.c +@@ -622,7 +622,10 @@ int CMS_decrypt_set1_pkey(CMS_ContentInf + STACK_OF(CMS_RecipientInfo) *ris; + CMS_RecipientInfo *ri; + int i, r; ++ int debug = 0; + ris = CMS_get0_RecipientInfos(cms); ++ if (ris) ++ debug = cms->d.envelopedData->encryptedContentInfo->debug; + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) + { + ri = sk_CMS_RecipientInfo_value(ris, i); +@@ -636,17 +639,38 @@ int CMS_decrypt_set1_pkey(CMS_ContentInf + CMS_RecipientInfo_set0_pkey(ri, pk); + r = CMS_RecipientInfo_decrypt(cms, ri); + CMS_RecipientInfo_set0_pkey(ri, NULL); +- if (r > 0) +- return 1; + if (cert) + { ++ /* If not debugging clear any error and ++ * return success to avoid leaking of ++ * information useful to MMA ++ */ ++ if (!debug) ++ { ++ ERR_clear_error(); ++ return 1; ++ } ++ if (r > 0) ++ return 1; + CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, + CMS_R_DECRYPT_ERROR); + return 0; + } +- ERR_clear_error(); ++ /* If no cert and not debugging don't leave loop ++ * after first successful decrypt. Always attempt ++ * to decrypt all recipients to avoid leaking timing ++ * of a successful decrypt. ++ */ ++ else if (r > 0 && debug) ++ return 1; + } + } ++ /* If no cert and not debugging always return success */ ++ if (!cert && !debug) ++ { ++ ERR_clear_error(); ++ return 1; ++ } + + CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT); + return 0; +@@ -705,9 +729,14 @@ int CMS_decrypt(CMS_ContentInfo *cms, EV + } + if (!dcont && !check_content(cms)) + return 0; ++ if (flags & CMS_DEBUG_DECRYPT) ++ cms->d.envelopedData->encryptedContentInfo->debug = 1; ++ else ++ cms->d.envelopedData->encryptedContentInfo->debug = 0; ++ if (!pk && !cert && !dcont && !out) ++ return 1; + if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) + return 0; +- + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; +Index: b/crypto/pkcs7/pk7_doit.c +=================================================================== +--- a/crypto/pkcs7/pk7_doit.c ++++ b/crypto/pkcs7/pk7_doit.c +@@ -423,6 +423,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + int max; + X509_OBJECT ret; + #endif ++ unsigned char *tkey = NULL; ++ int tkeylen; + int jj; + + if ((etmp=BIO_new(BIO_f_cipher())) == NULL) +@@ -464,36 +466,42 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + + if (pcert == NULL) + { ++ /* Temporary storage in case EVP_PKEY_decrypt ++ * overwrites output buffer on error. ++ */ ++ unsigned char *tmp2; ++ tmp2 = OPENSSL_malloc(jj); ++ if (!tmp2) ++ goto err; ++ jj = -1; ++ /* Always attempt to decrypt all cases to avoid ++ * leaking timing information about a successful ++ * decrypt. ++ */ + for (i=0; ienc_key), + M_ASN1_STRING_length(ri->enc_key), + pkey); +- if (jj > 0) +- break; ++ if (tret > 0) ++ { ++ memcpy(tmp, tmp2, tret); ++ OPENSSL_cleanse(tmp2, tret); ++ jj = tret; ++ } + ERR_clear_error(); +- ri = NULL; +- } +- if (ri == NULL) +- { +- PKCS7err(PKCS7_F_PKCS7_DATADECODE, +- PKCS7_R_NO_RECIPIENT_MATCHES_KEY); +- goto err; + } ++ OPENSSL_free(tmp2); + } + else + { + jj=EVP_PKEY_decrypt(tmp, + M_ASN1_STRING_data(ri->enc_key), + M_ASN1_STRING_length(ri->enc_key), pkey); +- if (jj <= 0) +- { +- PKCS7err(PKCS7_F_PKCS7_DATADECODE, +- ERR_R_EVP_LIB); +- goto err; +- } ++ ERR_clear_error(); + } + + evp_ctx=NULL; +@@ -502,24 +510,49 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + goto err; + if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) + goto err; ++ /* Generate random key to counter MMA */ ++ tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); ++ tkey = OPENSSL_malloc(tkeylen); ++ if (!tkey) ++ goto err; ++ if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) ++ goto err; ++ /* If we have no key use random key */ ++ if (jj <= 0) ++ { ++ OPENSSL_free(tmp); ++ jj = tkeylen; ++ tmp = tkey; ++ tkey = NULL; ++ } + +- if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { ++ if (jj != tkeylen) { + /* Some S/MIME clients don't use the same key + * and effective key length. The key length is + * determined by the size of the decrypted RSA key. + */ + if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) + { +- PKCS7err(PKCS7_F_PKCS7_DATADECODE, +- PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); +- goto err; ++ /* As MMA defence use random key instead */ ++ OPENSSL_cleanse(tmp, jj); ++ OPENSSL_free(tmp); ++ jj = tkeylen; ++ tmp = tkey; ++ tkey = NULL; + } + } ++ ERR_clear_error(); + if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) + goto err; + + OPENSSL_cleanse(tmp,jj); + ++ if (tkey) ++ { ++ OPENSSL_cleanse(tkey, tkeylen); ++ OPENSSL_free(tkey); ++ } ++ + if (out == NULL) + out=etmp; + else diff -Nru openssl098-0.9.8o/debian/patches/CVE-2012-2333.patch openssl098-0.9.8o/debian/patches/CVE-2012-2333.patch --- openssl098-0.9.8o/debian/patches/CVE-2012-2333.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssl098-0.9.8o/debian/patches/CVE-2012-2333.patch 2014-06-19 09:49:57.000000000 +0200 @@ -0,0 +1,25 @@ +Origin: http://cvs.openssl.org/chngview?cn=22558 +Subject: Sanity check record length before skipping explicit IV in + TLS 1.2, 1.1 and DTLS to fix DoS attack. + + *) Sanity check record length before skipping explicit IV in TLS + 1.2, 1.1 and DTLS to avoid DoS attack. + + Thanks to Codenomicon for discovering this issue using Fuzz-o-Matic + fuzzing as a service testing platform. + (CVE-2012-2333) + [Steve Henson] + +Index: openssl098-0.9.8o/ssl/d1_enc.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/d1_enc.c 2009-09-13 13:20:38.000000000 +0200 ++++ openssl098-0.9.8o/ssl/d1_enc.c 2014-06-18 11:55:37.116264708 +0200 +@@ -257,7 +257,7 @@ + } + /* TLS 1.0 does not bound the number of padding bytes by the block size. + * All of them must have value 'padding_length'. */ +- if (i > (int)rec->length) ++ if (i + bs > (int)rec->length) + { + /* Incorrect padding. SSLerr() and ssl3_alert are done + * by caller: we don't want to reveal whether this is diff -Nru openssl098-0.9.8o/debian/patches/CVE-2013-0166.patch openssl098-0.9.8o/debian/patches/CVE-2013-0166.patch --- openssl098-0.9.8o/debian/patches/CVE-2013-0166.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssl098-0.9.8o/debian/patches/CVE-2013-0166.patch 2014-06-19 09:49:57.000000000 +0200 @@ -0,0 +1,41 @@ +Description: fix denial of service via invalid OCSP key +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=66e8211c0b1347970096e04b18aa52567c325200 +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=699889 + +Index: openssl098-0.9.8o/crypto/asn1/a_verify.c +=================================================================== +--- openssl098-0.9.8o.orig/crypto/asn1/a_verify.c 2008-09-25 18:38:07.000000000 +0200 ++++ openssl098-0.9.8o/crypto/asn1/a_verify.c 2014-06-18 11:56:54.844266698 +0200 +@@ -138,6 +138,12 @@ + unsigned char *buf_in=NULL; + int ret= -1,i,inl; + ++ if (!pkey) ++ { ++ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); ++ return -1; ++ } ++ + EVP_MD_CTX_init(&ctx); + i=OBJ_obj2nid(a->algorithm); + type=EVP_get_digestbyname(OBJ_nid2sn(i)); +Index: openssl098-0.9.8o/crypto/ocsp/ocsp_vfy.c +=================================================================== +--- openssl098-0.9.8o.orig/crypto/ocsp/ocsp_vfy.c 2008-11-05 19:36:45.000000000 +0100 ++++ openssl098-0.9.8o/crypto/ocsp/ocsp_vfy.c 2014-06-18 11:56:54.848266698 +0200 +@@ -91,9 +91,12 @@ + { + EVP_PKEY *skey; + skey = X509_get_pubkey(signer); +- ret = OCSP_BASICRESP_verify(bs, skey, 0); +- EVP_PKEY_free(skey); +- if(ret <= 0) ++ if (skey) ++ { ++ ret = OCSP_BASICRESP_verify(bs, skey, 0); ++ EVP_PKEY_free(skey); ++ } ++ if(!skey || ret <= 0) + { + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); + goto end; diff -Nru openssl098-0.9.8o/debian/patches/CVE-2013-0169.patch openssl098-0.9.8o/debian/patches/CVE-2013-0169.patch --- openssl098-0.9.8o/debian/patches/CVE-2013-0169.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssl098-0.9.8o/debian/patches/CVE-2013-0169.patch 2014-06-19 09:49:58.000000000 +0200 @@ -0,0 +1,1912 @@ +Description: fix "Lucky Thirteen" timing side-channel TLS attack +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=270881316664396326c461ec7a124aec2c6cc081 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=35a65e814beb899fa1c69a7673a8956c6059dce7 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=a33e6702a0db1b9f4648d247b8b28a5c0e42ca13 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=2928cb4c82d6516d9e65ede4901a5957d8c39c32 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=b3a959a337b8083bc855623f24cebaf43a477350 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=be88529753897c29c677d1becb321f0072c0659c +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=99f5093347c65eecbd05f0668aea94b32fcf20d7 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=24b28060975c01b749391778d13ec2ea1323a1aa +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=924b11742296c13816a9f301e76fea023003920c +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=c23a7458209e773ffcd42bdcfa5cf2564df86bd7 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=1909df070fb5c5b87246a2de19c17588deba5818 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=33ccde59a1ece0f68cc4b64e930001ab230725b1 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=5f9345a2f0b592457fc4a619ac98ea59ffd394ba +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=40e0de03955e218f45a7979cb46fba193f4e7fc2 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=1213e6c3c2d7abeeb886d911a3c6c06c5da2e3a4 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=ca3b81c8580a609edac1f13a3f62d4348d66c3a8 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=6351adecb4726476def5f5ad904a7d2e63480d53 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=fb092ef4fca897344daf7189526f5f26be6487ce +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=59b1129e0a50fdf7e4e58d7c355783a7bfc1f44c +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=4ea7019165db53b92b4284461c5c88bfe7c6e57d +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=76c61a5d1adb92388f39e585e4af860a20feb9bb +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=ff58eaa4b645a38f3a226cf566d969fffa64ef94 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=5864fd2061f43dc8f89b5755f19bd2a35dec636c +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=fbe621d08f2026926c91c1c5f386b27605e39a43 +Origin: backport, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=a8655eb21a7f9a313db18daa6ccaed928fb6027c +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=699889 + +Index: openssl098-0.9.8o/crypto/bn/bn_word.c +=================================================================== +--- openssl098-0.9.8o.orig/crypto/bn/bn_word.c 2005-07-26 00:55:47.000000000 +0200 ++++ openssl098-0.9.8o/crypto/bn/bn_word.c 2014-06-18 11:58:59.116269880 +0200 +@@ -144,26 +144,17 @@ + a->neg=!(a->neg); + return(i); + } +- /* Only expand (and risk failing) if it's possibly necessary */ +- if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) && +- (bn_wexpand(a,a->top+1) == NULL)) +- return(0); +- i=0; +- for (;;) ++ for (i=0;w!=0 && itop;i++) + { +- if (i >= a->top) +- l=w; +- else +- l=(a->d[i]+w)&BN_MASK2; +- a->d[i]=l; +- if (w > l) +- w=1; +- else +- break; +- i++; ++ a->d[i] = l = (a->d[i]+w)&BN_MASK2; ++ w = (w>l)?1:0; + } +- if (i >= a->top) ++ if (w && i==a->top) ++ { ++ if (bn_wexpand(a,a->top+1) == NULL) return 0; + a->top++; ++ a->d[i]=w; ++ } + bn_check_top(a); + return(1); + } +Index: openssl098-0.9.8o/crypto/cryptlib.c +=================================================================== +--- openssl098-0.9.8o.orig/crypto/cryptlib.c 2009-09-13 13:20:36.000000000 +0200 ++++ openssl098-0.9.8o/crypto/cryptlib.c 2014-06-18 11:58:59.116269880 +0200 +@@ -543,3 +543,19 @@ + } + + void *OPENSSL_stderr(void) { return stderr; } ++ ++#ifndef OPENSSL_FIPS ++ ++int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) ++ { ++ size_t i; ++ const unsigned char *a = in_a; ++ const unsigned char *b = in_b; ++ unsigned char x = 0; ++ ++ for (i = 0; i < len; i++) ++ x |= a[i] ^ b[i]; ++ ++ return x; ++ } ++#endif +Index: openssl098-0.9.8o/crypto/crypto.h +=================================================================== +--- openssl098-0.9.8o.orig/crypto/crypto.h 2008-10-26 19:42:00.000000000 +0100 ++++ openssl098-0.9.8o/crypto/crypto.h 2014-06-18 11:58:59.120269880 +0200 +@@ -588,6 +588,13 @@ + + #endif /* def OPENSSL_FIPS */ + ++/* CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It ++ * takes an amount of time dependent on |len|, but independent of the contents ++ * of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a ++ * defined order as the return value when a != b is undefined, other than to be ++ * non-zero. */ ++int CRYPTO_memcmp(const void *a, const void *b, size_t len); ++ + /* BEGIN ERROR CODES */ + /* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. +Index: openssl098-0.9.8o/crypto/o_init.c +=================================================================== +--- openssl098-0.9.8o.orig/crypto/o_init.c 2010-03-25 13:17:15.000000000 +0100 ++++ openssl098-0.9.8o/crypto/o_init.c 2014-06-18 11:58:59.120269880 +0200 +@@ -93,4 +93,18 @@ + #endif + } + ++#ifdef OPENSSL_FIPS + ++int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) ++ { ++ size_t i; ++ const unsigned char *a = in_a; ++ const unsigned char *b = in_b; ++ unsigned char x = 0; ++ ++ for (i = 0; i < len; i++) ++ x |= a[i] ^ b[i]; ++ ++ return x; ++ } ++#endif +Index: openssl098-0.9.8o/crypto/rsa/rsa_oaep.c +=================================================================== +--- openssl098-0.9.8o.orig/crypto/rsa/rsa_oaep.c 2009-06-27 01:56:10.000000000 +0200 ++++ openssl098-0.9.8o/crypto/rsa/rsa_oaep.c 2014-06-18 11:58:59.120269880 +0200 +@@ -143,7 +143,7 @@ + + EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL); + +- if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad) ++ if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad) + goto decoding_err; + else + { +Index: openssl098-0.9.8o/ssl/d1_enc.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/d1_enc.c 2014-06-18 11:55:37.116264708 +0200 ++++ openssl098-0.9.8o/ssl/d1_enc.c 2014-06-18 11:58:59.120269880 +0200 +@@ -126,18 +126,30 @@ + #include + #endif + ++/* dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. ++ * ++ * Returns: ++ * 0: (in non-constant time) if the record is publically invalid (i.e. too ++ * short etc). ++ * 1: if the record's padding is valid / the encryption was successful. ++ * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, ++ * an internal error occured. */ + int dtls1_enc(SSL *s, int send) + { + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; +- int bs,i,ii,j,k,n=0; ++ int bs,i,j,k,n=0; + const EVP_CIPHER *enc; + + if (send) + { + if (s->write_hash != NULL) ++ { + n=EVP_MD_size(s->write_hash); ++ if (n < 0) ++ return -1; ++ } + ds=s->enc_write_ctx; + rec= &(s->s3->wrec); + if (s->enc_write_ctx == NULL) +@@ -159,7 +171,10 @@ + else + { + if (s->read_hash != NULL) ++ { + n=EVP_MD_size(s->read_hash); ++ OPENSSL_assert(n >= 0); ++ } + ds=s->enc_read_ctx; + rec= &(s->s3->rrec); + if (s->enc_read_ctx == NULL) +@@ -243,43 +258,7 @@ + #endif /* KSSL_DEBUG */ + + if ((bs != 1) && !send) +- { +- ii=i=rec->data[l-1]; /* padding_length */ +- i++; +- if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) +- { +- /* First packet is even in size, so check */ +- if ((memcmp(s->s3->read_sequence, +- "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) +- s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; +- if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) +- i--; +- } +- /* TLS 1.0 does not bound the number of padding bytes by the block size. +- * All of them must have value 'padding_length'. */ +- if (i + bs > (int)rec->length) +- { +- /* Incorrect padding. SSLerr() and ssl3_alert are done +- * by caller: we don't want to reveal whether this is +- * a decryption error or a MAC verification failure +- * (see http://www.openssl.org/~bodo/tls-cbc.txt) +- */ +- return -1; +- } +- for (j=(int)(l-i); j<(int)l; j++) +- { +- if (rec->data[j] != ii) +- { +- /* Incorrect padding */ +- return -1; +- } +- } +- rec->length-=i; +- +- rec->data += bs; /* skip the implicit IV */ +- rec->input += bs; +- rec->length -= bs; +- } ++ return tls1_cbc_remove_padding(s, rec, bs, n); + } + return(1); + } +Index: openssl098-0.9.8o/ssl/d1_pkt.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/d1_pkt.c 2014-06-17 15:43:29.000000000 +0200 ++++ openssl098-0.9.8o/ssl/d1_pkt.c 2014-06-18 11:58:59.120269880 +0200 +@@ -332,15 +332,11 @@ + dtls1_process_record(SSL *s) + { + int i,al; +- int clear=0; + int enc_err; + SSL_SESSION *sess; +- SSL3_RECORD *rr; +- unsigned int mac_size; ++ SSL3_RECORD *rr; ++ unsigned int mac_size, orig_len; + unsigned char md[EVP_MAX_MD_SIZE]; +- int decryption_failed_or_bad_record_mac = 0; +- unsigned char *mac = NULL; +- + + rr= &(s->s3->rrec); + sess = s->session; +@@ -372,12 +368,16 @@ + rr->data=rr->input; + + enc_err = s->method->ssl3_enc->enc(s,0); +- if (enc_err <= 0) ++ /* enc_err is: ++ * 0: (in non-constant time) if the record is publically invalid. ++ * 1: if the padding is valid ++ * -1: if the padding is invalid */ ++ if (enc_err == 0) + { +- /* To minimize information leaked via timing, we will always +- * perform all computations before discarding the message. +- */ +- decryption_failed_or_bad_record_mac = 1; ++ /* For DTLS we simply ignore bad packets. */ ++ rr->length = 0; ++ s->packet_length = 0; ++ goto err; + } + + #ifdef TLS_DEBUG +@@ -387,41 +387,62 @@ + #endif + + /* r->length is now the compressed data plus mac */ +-if ( (sess == NULL) || +- (s->enc_read_ctx == NULL) || +- (s->read_hash == NULL)) +- clear=1; +- +- if (!clear) ++ if ((sess != NULL) && ++ (s->enc_read_ctx != NULL) && ++ (s->read_hash != NULL)) + { ++ /* s->read_hash != NULL => mac_size != -1 */ ++ unsigned char *mac = NULL; ++ unsigned char mac_tmp[EVP_MAX_MD_SIZE]; + mac_size=EVP_MD_size(s->read_hash); ++ OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); + +- if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) ++ /* kludge: *_cbc_remove_padding passes padding length in rr->type */ ++ orig_len = rr->length+((unsigned int)rr->type>>8); ++ ++ /* orig_len is the length of the record before any padding was ++ * removed. This is public information, as is the MAC in use, ++ * therefore we can safely process the record in a different ++ * amount of time if it's too short to possibly contain a MAC. ++ */ ++ if (orig_len < mac_size || ++ /* CBC records must have a padding length byte too. */ ++ (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && ++ orig_len < mac_size+1)) + { +-#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ +- al=SSL_AD_RECORD_OVERFLOW; +- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); ++ al=SSL_AD_DECODE_ERROR; ++ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT); + goto f_err; +-#else +- decryption_failed_or_bad_record_mac = 1; +-#endif + } +- /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ +- if (rr->length >= mac_size) ++ ++ if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) + { ++ /* We update the length so that the TLS header bytes ++ * can be constructed correctly but we need to extract ++ * the MAC in constant time from within the record, ++ * without leaking the contents of the padding bytes. ++ * */ ++ mac = mac_tmp; ++ ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); + rr->length -= mac_size; +- mac = &rr->data[rr->length]; + } + else +- rr->length = 0; +- i=s->method->ssl3_enc->mac(s,md,0); +- if (mac == NULL || memcmp(md, mac, mac_size) != 0) + { +- decryption_failed_or_bad_record_mac = 1; ++ /* In this case there's no padding, so |orig_len| ++ * equals |rec->length| and we checked that there's ++ * enough bytes for |mac_size| above. */ ++ rr->length -= mac_size; ++ mac = &rr->data[rr->length]; + } ++ ++ i=s->method->ssl3_enc->mac(s,md,0 /* not send */); ++ if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) ++ enc_err = -1; ++ if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) ++ enc_err = -1; + } + +- if (decryption_failed_or_bad_record_mac) ++ if (enc_err < 0) + { + /* decryption failed, silently discard message */ + rr->length = 0; +Index: openssl098-0.9.8o/ssl/Makefile +=================================================================== +--- openssl098-0.9.8o.orig/ssl/Makefile 2010-01-20 17:35:30.000000000 +0100 ++++ openssl098-0.9.8o/ssl/Makefile 2014-06-18 11:58:59.120269880 +0200 +@@ -22,7 +22,7 @@ + SHARED_LIB= libssl$(SHLIB_EXT) + LIBSRC= \ + s2_meth.c s2_srvr.c s2_clnt.c s2_lib.c s2_enc.c s2_pkt.c \ +- s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c \ ++ s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c s3_cbc.c \ + s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c s23_pkt.c \ + t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c \ + d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \ +@@ -33,7 +33,7 @@ + bio_ssl.c ssl_err.c kssl.c t1_reneg.c + LIBOBJ= \ + s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \ +- s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \ ++ s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o s3_cbc.o \ + s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o s23_pkt.o \ + t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o \ + d1_meth.o d1_srvr.o d1_clnt.o d1_lib.o d1_pkt.o \ +Index: openssl098-0.9.8o/ssl/s2_clnt.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/s2_clnt.c 2009-01-07 11:48:23.000000000 +0100 ++++ openssl098-0.9.8o/ssl/s2_clnt.c 2014-06-18 11:58:59.120269880 +0200 +@@ -935,7 +935,7 @@ + s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */ + p += 1; + +- if (memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0) ++ if (CRYPTO_memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0) + { + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT); +Index: openssl098-0.9.8o/ssl/s2_pkt.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/s2_pkt.c 2003-12-27 17:10:30.000000000 +0100 ++++ openssl098-0.9.8o/ssl/s2_pkt.c 2014-06-18 11:58:59.120269880 +0200 +@@ -267,8 +267,7 @@ + s->s2->ract_data_length-=mac_size; + ssl2_mac(s,mac,0); + s->s2->ract_data_length-=s->s2->padding; +- if ( (memcmp(mac,s->s2->mac_data, +- (unsigned int)mac_size) != 0) || ++ if ( (CRYPTO_memcmp(mac,s->s2->mac_data,mac_size) != 0) || + (s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0)) + { + SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE); +Index: openssl098-0.9.8o/ssl/s3_both.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/s3_both.c 2010-03-25 00:16:35.000000000 +0100 ++++ openssl098-0.9.8o/ssl/s3_both.c 2014-06-18 11:58:59.124269880 +0200 +@@ -242,7 +242,7 @@ + goto f_err; + } + +- if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) ++ if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) + { + al=SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED); +Index: openssl098-0.9.8o/ssl/s3_cbc.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ openssl098-0.9.8o/ssl/s3_cbc.c 2014-06-18 11:58:59.124269880 +0200 +@@ -0,0 +1,783 @@ ++/* ssl/s3_cbc.c */ ++/* ==================================================================== ++ * Copyright (c) 2012 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. ++ * ==================================================================== ++ * ++ * This product includes cryptographic software written by Eric Young ++ * (eay@cryptsoft.com). This product includes software written by Tim ++ * Hudson (tjh@cryptsoft.com). ++ * ++ */ ++ ++#include "ssl_locl.h" ++ ++#include ++#include ++ ++/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length ++ * field. (SHA-384/512 have 128-bit length.) */ ++#define MAX_HASH_BIT_COUNT_BYTES 16 ++ ++/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support. ++ * Currently SHA-384/512 has a 128-byte block size and that's the largest ++ * supported by TLS.) */ ++#define MAX_HASH_BLOCK_SIZE 128 ++ ++/* Some utility functions are needed: ++ * ++ * These macros return the given value with the MSB copied to all the other ++ * bits. They use the fact that arithmetic shift shifts-in the sign bit. ++ * However, this is not ensured by the C standard so you may need to replace ++ * them with something else on odd CPUs. */ ++#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) ) ++#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x))) ++ ++/* constant_time_lt returns 0xff if a=b and 0x00 otherwise. */ ++static unsigned constant_time_ge(unsigned a, unsigned b) ++ { ++ a -= b; ++ return DUPLICATE_MSB_TO_ALL(~a); ++ } ++ ++/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */ ++static unsigned char constant_time_eq_8(unsigned a, unsigned b) ++ { ++ unsigned c = a ^ b; ++ c--; ++ return DUPLICATE_MSB_TO_ALL_8(c); ++ } ++ ++/* ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC ++ * record in |rec| by updating |rec->length| in constant time. ++ * ++ * block_size: the block size of the cipher used to encrypt the record. ++ * returns: ++ * 0: (in non-constant time) if the record is publicly invalid. ++ * 1: if the padding was valid ++ * -1: otherwise. */ ++int ssl3_cbc_remove_padding(const SSL* s, ++ SSL3_RECORD *rec, ++ unsigned block_size, ++ unsigned mac_size) ++ { ++ unsigned padding_length, good; ++ const unsigned overhead = 1 /* padding length byte */ + mac_size; ++ ++ /* These lengths are all public so we can test them in non-constant ++ * time. */ ++ if (overhead > rec->length) ++ return 0; ++ ++ padding_length = rec->data[rec->length-1]; ++ good = constant_time_ge(rec->length, padding_length+overhead); ++ /* SSLv3 requires that the padding is minimal. */ ++ good &= constant_time_ge(block_size, padding_length+1); ++ padding_length = good & (padding_length+1); ++ rec->length -= padding_length; ++ rec->type |= padding_length<<8; /* kludge: pass padding length */ ++ return (int)((good & 1) | (~good & -1)); ++} ++ ++/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC ++ * record in |rec| in constant time and returns 1 if the padding is valid and ++ * -1 otherwise. It also removes any explicit IV from the start of the record ++ * without leaking any timing about whether there was enough space after the ++ * padding was removed. ++ * ++ * block_size: the block size of the cipher used to encrypt the record. ++ * returns: ++ * 0: (in non-constant time) if the record is publicly invalid. ++ * 1: if the padding was valid ++ * -1: otherwise. */ ++int tls1_cbc_remove_padding(const SSL* s, ++ SSL3_RECORD *rec, ++ unsigned block_size, ++ unsigned mac_size) ++ { ++ unsigned padding_length, good, to_check, i; ++ const unsigned overhead = 1 /* padding length byte */ + mac_size; ++ /* Check if version requires explicit IV */ ++ if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) ++ { ++ /* These lengths are all public so we can test them in ++ * non-constant time. ++ */ ++ if (overhead + block_size > rec->length) ++ return 0; ++ /* We can now safely skip explicit IV */ ++ rec->data += block_size; ++ rec->input += block_size; ++ rec->length -= block_size; ++ } ++ else if (overhead > rec->length) ++ return 0; ++ ++ padding_length = rec->data[rec->length-1]; ++ ++ /* NB: if compression is in operation the first packet may not be of ++ * even length so the padding bug check cannot be performed. This bug ++ * workaround has been around since SSLeay so hopefully it is either ++ * fixed now or no buggy implementation supports compression [steve] ++ */ ++ if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand) ++ { ++ /* First packet is even in size, so check */ ++ if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0",8) == 0) && ++ !(padding_length & 1)) ++ { ++ s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; ++ } ++ if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) && ++ padding_length > 0) ++ { ++ padding_length--; ++ } ++ } ++ ++ good = constant_time_ge(rec->length, overhead+padding_length); ++ /* The padding consists of a length byte at the end of the record and ++ * then that many bytes of padding, all with the same value as the ++ * length byte. Thus, with the length byte included, there are i+1 ++ * bytes of padding. ++ * ++ * We can't check just |padding_length+1| bytes because that leaks ++ * decrypted information. Therefore we always have to check the maximum ++ * amount of padding possible. (Again, the length of the record is ++ * public information so we can use it.) */ ++ to_check = 255; /* maximum amount of padding. */ ++ if (to_check > rec->length-1) ++ to_check = rec->length-1; ++ ++ for (i = 0; i < to_check; i++) ++ { ++ unsigned char mask = constant_time_ge(padding_length, i); ++ unsigned char b = rec->data[rec->length-1-i]; ++ /* The final |padding_length+1| bytes should all have the value ++ * |padding_length|. Therefore the XOR should be zero. */ ++ good &= ~(mask&(padding_length ^ b)); ++ } ++ ++ /* If any of the final |padding_length+1| bytes had the wrong value, ++ * one or more of the lower eight bits of |good| will be cleared. We ++ * AND the bottom 8 bits together and duplicate the result to all the ++ * bits. */ ++ good &= good >> 4; ++ good &= good >> 2; ++ good &= good >> 1; ++ good <<= sizeof(good)*8-1; ++ good = DUPLICATE_MSB_TO_ALL(good); ++ ++ padding_length = good & (padding_length+1); ++ rec->length -= padding_length; ++ rec->type |= padding_length<<8; /* kludge: pass padding length */ ++ ++ return (int)((good & 1) | (~good & -1)); ++ } ++ ++/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in ++ * constant time (independent of the concrete value of rec->length, which may ++ * vary within a 256-byte window). ++ * ++ * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to ++ * this function. ++ * ++ * On entry: ++ * rec->orig_len >= md_size ++ * md_size <= EVP_MAX_MD_SIZE ++ * ++ * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with ++ * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into ++ * a single or pair of cache-lines, then the variable memory accesses don't ++ * actually affect the timing. CPUs with smaller cache-lines [if any] are ++ * not multi-core and are not considered vulnerable to cache-timing attacks. ++ */ ++#define CBC_MAC_ROTATE_IN_PLACE ++ ++void ssl3_cbc_copy_mac(unsigned char* out, ++ const SSL3_RECORD *rec, ++ unsigned md_size,unsigned orig_len) ++ { ++#if defined(CBC_MAC_ROTATE_IN_PLACE) ++ unsigned char rotated_mac_buf[64+EVP_MAX_MD_SIZE]; ++ unsigned char *rotated_mac; ++#else ++ unsigned char rotated_mac[EVP_MAX_MD_SIZE]; ++#endif ++ ++ /* mac_end is the index of |rec->data| just after the end of the MAC. */ ++ unsigned mac_end = rec->length; ++ unsigned mac_start = mac_end - md_size; ++ /* scan_start contains the number of bytes that we can ignore because ++ * the MAC's position can only vary by 255 bytes. */ ++ unsigned scan_start = 0; ++ unsigned i, j; ++ unsigned div_spoiler; ++ unsigned rotate_offset; ++ ++ OPENSSL_assert(orig_len >= md_size); ++ OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); ++ ++#if defined(CBC_MAC_ROTATE_IN_PLACE) ++ rotated_mac = rotated_mac_buf + ((0-(size_t)rotated_mac_buf)&63); ++#endif ++ ++ /* This information is public so it's safe to branch based on it. */ ++ if (orig_len > md_size + 255 + 1) ++ scan_start = orig_len - (md_size + 255 + 1); ++ /* div_spoiler contains a multiple of md_size that is used to cause the ++ * modulo operation to be constant time. Without this, the time varies ++ * based on the amount of padding when running on Intel chips at least. ++ * ++ * The aim of right-shifting md_size is so that the compiler doesn't ++ * figure out that it can remove div_spoiler as that would require it ++ * to prove that md_size is always even, which I hope is beyond it. */ ++ div_spoiler = md_size >> 1; ++ div_spoiler <<= (sizeof(div_spoiler)-1)*8; ++ rotate_offset = (div_spoiler + mac_start - scan_start) % md_size; ++ ++ memset(rotated_mac, 0, md_size); ++ for (i = scan_start, j = 0; i < orig_len; i++) ++ { ++ unsigned char mac_started = constant_time_ge(i, mac_start); ++ unsigned char mac_ended = constant_time_ge(i, mac_end); ++ unsigned char b = rec->data[i]; ++ rotated_mac[j++] |= b & mac_started & ~mac_ended; ++ j &= constant_time_lt(j,md_size); ++ } ++ ++ /* Now rotate the MAC */ ++#if defined(CBC_MAC_ROTATE_IN_PLACE) ++ j = 0; ++ for (i = 0; i < md_size; i++) ++ { ++ /* in case cache-line is 32 bytes, touch second line */ ++ ((volatile unsigned char *)rotated_mac)[rotate_offset^32]; ++ out[j++] = rotated_mac[rotate_offset++]; ++ rotate_offset &= constant_time_lt(rotate_offset,md_size); ++ } ++#else ++ memset(out, 0, md_size); ++ rotate_offset = md_size - rotate_offset; ++ rotate_offset &= constant_time_lt(rotate_offset,md_size); ++ for (i = 0; i < md_size; i++) ++ { ++ for (j = 0; j < md_size; j++) ++ out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset); ++ rotate_offset++; ++ rotate_offset &= constant_time_lt(rotate_offset,md_size); ++ } ++#endif ++ } ++ ++/* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in ++ * little-endian order. The value of p is advanced by four. */ ++#define u32toLE(n, p) \ ++ (*((p)++)=(unsigned char)(n), \ ++ *((p)++)=(unsigned char)(n>>8), \ ++ *((p)++)=(unsigned char)(n>>16), \ ++ *((p)++)=(unsigned char)(n>>24)) ++ ++/* These functions serialize the state of a hash and thus perform the standard ++ * "final" operation without adding the padding and length that such a function ++ * typically does. */ ++static void tls1_md5_final_raw(void* ctx, unsigned char *md_out) ++ { ++ MD5_CTX *md5 = ctx; ++ u32toLE(md5->A, md_out); ++ u32toLE(md5->B, md_out); ++ u32toLE(md5->C, md_out); ++ u32toLE(md5->D, md_out); ++ } ++ ++static void tls1_sha1_final_raw(void* ctx, unsigned char *md_out) ++ { ++ SHA_CTX *sha1 = ctx; ++ l2n(sha1->h0, md_out); ++ l2n(sha1->h1, md_out); ++ l2n(sha1->h2, md_out); ++ l2n(sha1->h3, md_out); ++ l2n(sha1->h4, md_out); ++ } ++#define LARGEST_DIGEST_CTX SHA_CTX ++ ++#ifndef OPENSSL_NO_SHA256 ++static void tls1_sha256_final_raw(void* ctx, unsigned char *md_out) ++ { ++ SHA256_CTX *sha256 = ctx; ++ unsigned i; ++ ++ for (i = 0; i < 8; i++) ++ { ++ l2n(sha256->h[i], md_out); ++ } ++ } ++#undef LARGEST_DIGEST_CTX ++#define LARGEST_DIGEST_CTX SHA256_CTX ++#endif ++ ++#ifndef OPENSSL_NO_SHA512 ++static void tls1_sha512_final_raw(void* ctx, unsigned char *md_out) ++ { ++ SHA512_CTX *sha512 = ctx; ++ unsigned i; ++ ++ for (i = 0; i < 8; i++) ++ { ++ l2n8(sha512->h[i], md_out); ++ } ++ } ++#undef LARGEST_DIGEST_CTX ++#define LARGEST_DIGEST_CTX SHA512_CTX ++#endif ++ ++/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function ++ * which ssl3_cbc_digest_record supports. */ ++char ssl3_cbc_record_digest_supported(const EVP_MD *digest) ++ { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode()) ++ return 0; ++#endif ++ switch (EVP_MD_type(digest)) ++ { ++ case NID_md5: ++ case NID_sha1: ++#ifndef OPENSSL_NO_SHA256 ++ case NID_sha224: ++ case NID_sha256: ++#endif ++#ifndef OPENSSL_NO_SHA512 ++ case NID_sha384: ++ case NID_sha512: ++#endif ++ return 1; ++ default: ++ return 0; ++ } ++ } ++ ++/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS ++ * record. ++ * ++ * ctx: the EVP_MD_CTX from which we take the hash function. ++ * ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX. ++ * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. ++ * md_out_size: if non-NULL, the number of output bytes is written here. ++ * header: the 13-byte, TLS record header. ++ * data: the record data itself, less any preceeding explicit IV. ++ * data_plus_mac_size: the secret, reported length of the data and MAC ++ * once the padding has been removed. ++ * data_plus_mac_plus_padding_size: the public length of the whole ++ * record, including padding. ++ * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS. ++ * ++ * On entry: by virtue of having been through one of the remove_padding ++ * functions, above, we know that data_plus_mac_size is large enough to contain ++ * a padding byte and MAC. (If the padding was invalid, it might contain the ++ * padding too. ) */ ++void ssl3_cbc_digest_record( ++ const EVP_MD *digest, ++ unsigned char* md_out, ++ size_t* md_out_size, ++ const unsigned char header[13], ++ const unsigned char *data, ++ size_t data_plus_mac_size, ++ size_t data_plus_mac_plus_padding_size, ++ const unsigned char *mac_secret, ++ unsigned mac_secret_length, ++ char is_sslv3) ++ { ++ union { double align; ++ unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; } md_state; ++ void (*md_final_raw)(void *ctx, unsigned char *md_out); ++ void (*md_transform)(void *ctx, const unsigned char *block); ++ unsigned md_size, md_block_size = 64; ++ unsigned sslv3_pad_length = 40, header_length, variance_blocks, ++ len, max_mac_bytes, num_blocks, ++ num_starting_blocks, k, mac_end_offset, c, index_a, index_b; ++ unsigned int bits; /* at most 18 bits */ ++ unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES]; ++ /* hmac_pad is the masked HMAC key. */ ++ unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE]; ++ unsigned char first_block[MAX_HASH_BLOCK_SIZE]; ++ unsigned char mac_out[EVP_MAX_MD_SIZE]; ++ unsigned i, j, md_out_size_u; ++ EVP_MD_CTX md_ctx; ++ /* mdLengthSize is the number of bytes in the length field that terminates ++ * the hash. */ ++ unsigned md_length_size = 8; ++ char length_is_big_endian = 1; ++ ++ /* This is a, hopefully redundant, check that allows us to forget about ++ * many possible overflows later in this function. */ ++ OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024); ++ ++ switch (EVP_MD_type(digest)) ++ { ++ case NID_md5: ++ MD5_Init((MD5_CTX*)md_state.c); ++ md_final_raw = tls1_md5_final_raw; ++ md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform; ++ md_size = 16; ++ sslv3_pad_length = 48; ++ length_is_big_endian = 0; ++ break; ++ case NID_sha1: ++ SHA1_Init((SHA_CTX*)md_state.c); ++ md_final_raw = tls1_sha1_final_raw; ++ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform; ++ md_size = 20; ++ break; ++#ifndef OPENSSL_NO_SHA256 ++ case NID_sha224: ++ SHA224_Init((SHA256_CTX*)md_state.c); ++ md_final_raw = tls1_sha256_final_raw; ++ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; ++ md_size = 224/8; ++ break; ++ case NID_sha256: ++ SHA256_Init((SHA256_CTX*)md_state.c); ++ md_final_raw = tls1_sha256_final_raw; ++ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; ++ md_size = 32; ++ break; ++#endif ++#ifndef OPENSSL_NO_SHA512 ++ case NID_sha384: ++ SHA384_Init((SHA512_CTX*)md_state.c); ++ md_final_raw = tls1_sha512_final_raw; ++ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; ++ md_size = 384/8; ++ md_block_size = 128; ++ md_length_size = 16; ++ break; ++ case NID_sha512: ++ SHA512_Init((SHA512_CTX*)md_state.c); ++ md_final_raw = tls1_sha512_final_raw; ++ md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; ++ md_size = 64; ++ md_block_size = 128; ++ md_length_size = 16; ++ break; ++#endif ++ default: ++ /* ssl3_cbc_record_digest_supported should have been ++ * called first to check that the hash function is ++ * supported. */ ++ OPENSSL_assert(0); ++ if (md_out_size) ++ *md_out_size = -1; ++ return; ++ } ++ ++ OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); ++ OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE); ++ OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); ++ ++ header_length = 13; ++ if (is_sslv3) ++ { ++ header_length = ++ mac_secret_length + ++ sslv3_pad_length + ++ 8 /* sequence number */ + ++ 1 /* record type */ + ++ 2 /* record length */; ++ } ++ ++ /* variance_blocks is the number of blocks of the hash that we have to ++ * calculate in constant time because they could be altered by the ++ * padding value. ++ * ++ * In SSLv3, the padding must be minimal so the end of the plaintext ++ * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that ++ * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash ++ * termination (0x80 + 64-bit length) don't fit in the final block, we ++ * say that the final two blocks can vary based on the padding. ++ * ++ * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not ++ * required to be minimal. Therefore we say that the final six blocks ++ * can vary based on the padding. ++ * ++ * Later in the function, if the message is short and there obviously ++ * cannot be this many blocks then variance_blocks can be reduced. */ ++ variance_blocks = is_sslv3 ? 2 : 6; ++ /* From now on we're dealing with the MAC, which conceptually has 13 ++ * bytes of `header' before the start of the data (TLS) or 71/75 bytes ++ * (SSLv3) */ ++ len = data_plus_mac_plus_padding_size + header_length; ++ /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including ++ * |header|, assuming that there's no padding. */ ++ max_mac_bytes = len - md_size - 1; ++ /* num_blocks is the maximum number of hash blocks. */ ++ num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size; ++ /* In order to calculate the MAC in constant time we have to handle ++ * the final blocks specially because the padding value could cause the ++ * end to appear somewhere in the final |variance_blocks| blocks and we ++ * can't leak where. However, |num_starting_blocks| worth of data can ++ * be hashed right away because no padding value can affect whether ++ * they are plaintext. */ ++ num_starting_blocks = 0; ++ /* k is the starting byte offset into the conceptual header||data where ++ * we start processing. */ ++ k = 0; ++ /* mac_end_offset is the index just past the end of the data to be ++ * MACed. */ ++ mac_end_offset = data_plus_mac_size + header_length - md_size; ++ /* c is the index of the 0x80 byte in the final hash block that ++ * contains application data. */ ++ c = mac_end_offset % md_block_size; ++ /* index_a is the hash block number that contains the 0x80 terminating ++ * value. */ ++ index_a = mac_end_offset / md_block_size; ++ /* index_b is the hash block number that contains the 64-bit hash ++ * length, in bits. */ ++ index_b = (mac_end_offset + md_length_size) / md_block_size; ++ /* bits is the hash-length in bits. It includes the additional hash ++ * block for the masked HMAC key, or whole of |header| in the case of ++ * SSLv3. */ ++ ++ /* For SSLv3, if we're going to have any starting blocks then we need ++ * at least two because the header is larger than a single block. */ ++ if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) ++ { ++ num_starting_blocks = num_blocks - variance_blocks; ++ k = md_block_size*num_starting_blocks; ++ } ++ ++ bits = 8*mac_end_offset; ++ if (!is_sslv3) ++ { ++ /* Compute the initial HMAC block. For SSLv3, the padding and ++ * secret bytes are included in |header| because they take more ++ * than a single block. */ ++ bits += 8*md_block_size; ++ memset(hmac_pad, 0, md_block_size); ++ OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad)); ++ memcpy(hmac_pad, mac_secret, mac_secret_length); ++ for (i = 0; i < md_block_size; i++) ++ hmac_pad[i] ^= 0x36; ++ ++ md_transform(md_state.c, hmac_pad); ++ } ++ ++ if (length_is_big_endian) ++ { ++ memset(length_bytes,0,md_length_size-4); ++ length_bytes[md_length_size-4] = (unsigned char)(bits>>24); ++ length_bytes[md_length_size-3] = (unsigned char)(bits>>16); ++ length_bytes[md_length_size-2] = (unsigned char)(bits>>8); ++ length_bytes[md_length_size-1] = (unsigned char)bits; ++ } ++ else ++ { ++ memset(length_bytes,0,md_length_size); ++ length_bytes[md_length_size-5] = (unsigned char)(bits>>24); ++ length_bytes[md_length_size-6] = (unsigned char)(bits>>16); ++ length_bytes[md_length_size-7] = (unsigned char)(bits>>8); ++ length_bytes[md_length_size-8] = (unsigned char)bits; ++ } ++ ++ if (k > 0) ++ { ++ if (is_sslv3) ++ { ++ /* The SSLv3 header is larger than a single block. ++ * overhang is the number of bytes beyond a single ++ * block that the header consumes: either 7 bytes ++ * (SHA1) or 11 bytes (MD5). */ ++ unsigned overhang = header_length-md_block_size; ++ md_transform(md_state.c, header); ++ memcpy(first_block, header + md_block_size, overhang); ++ memcpy(first_block + overhang, data, md_block_size-overhang); ++ md_transform(md_state.c, first_block); ++ for (i = 1; i < k/md_block_size - 1; i++) ++ md_transform(md_state.c, data + md_block_size*i - overhang); ++ } ++ else ++ { ++ /* k is a multiple of md_block_size. */ ++ memcpy(first_block, header, 13); ++ memcpy(first_block+13, data, md_block_size-13); ++ md_transform(md_state.c, first_block); ++ for (i = 1; i < k/md_block_size; i++) ++ md_transform(md_state.c, data + md_block_size*i - 13); ++ } ++ } ++ ++ memset(mac_out, 0, sizeof(mac_out)); ++ ++ /* We now process the final hash blocks. For each block, we construct ++ * it in constant time. If the |i==index_a| then we'll include the 0x80 ++ * bytes and zero pad etc. For each block we selectively copy it, in ++ * constant time, to |mac_out|. */ ++ for (i = num_starting_blocks; i <= num_starting_blocks+variance_blocks; i++) ++ { ++ unsigned char block[MAX_HASH_BLOCK_SIZE]; ++ unsigned char is_block_a = constant_time_eq_8(i, index_a); ++ unsigned char is_block_b = constant_time_eq_8(i, index_b); ++ for (j = 0; j < md_block_size; j++) ++ { ++ unsigned char b = 0, is_past_c, is_past_cp1; ++ if (k < header_length) ++ b = header[k]; ++ else if (k < data_plus_mac_plus_padding_size + header_length) ++ b = data[k-header_length]; ++ k++; ++ ++ is_past_c = is_block_a & constant_time_ge(j, c); ++ is_past_cp1 = is_block_a & constant_time_ge(j, c+1); ++ /* If this is the block containing the end of the ++ * application data, and we are at the offset for the ++ * 0x80 value, then overwrite b with 0x80. */ ++ b = (b&~is_past_c) | (0x80&is_past_c); ++ /* If this the the block containing the end of the ++ * application data and we're past the 0x80 value then ++ * just write zero. */ ++ b = b&~is_past_cp1; ++ /* If this is index_b (the final block), but not ++ * index_a (the end of the data), then the 64-bit ++ * length didn't fit into index_a and we're having to ++ * add an extra block of zeros. */ ++ b &= ~is_block_b | is_block_a; ++ ++ /* The final bytes of one of the blocks contains the ++ * length. */ ++ if (j >= md_block_size - md_length_size) ++ { ++ /* If this is index_b, write a length byte. */ ++ b = (b&~is_block_b) | (is_block_b&length_bytes[j-(md_block_size-md_length_size)]); ++ } ++ block[j] = b; ++ } ++ ++ md_transform(md_state.c, block); ++ md_final_raw(md_state.c, block); ++ /* If this is index_b, copy the hash value to |mac_out|. */ ++ for (j = 0; j < md_size; j++) ++ mac_out[j] |= block[j]&is_block_b; ++ } ++ ++ EVP_MD_CTX_init(&md_ctx); ++ EVP_DigestInit_ex(&md_ctx, digest, NULL /* engine */); ++ if (is_sslv3) ++ { ++ /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */ ++ memset(hmac_pad, 0x5c, sslv3_pad_length); ++ ++ EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length); ++ EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length); ++ EVP_DigestUpdate(&md_ctx, mac_out, md_size); ++ } ++ else ++ { ++ /* Complete the HMAC in the standard manner. */ ++ for (i = 0; i < md_block_size; i++) ++ hmac_pad[i] ^= 0x6a; ++ ++ EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size); ++ EVP_DigestUpdate(&md_ctx, mac_out, md_size); ++ } ++ EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); ++ if (md_out_size) ++ *md_out_size = md_out_size_u; ++ EVP_MD_CTX_cleanup(&md_ctx); ++ } ++ ++#ifdef OPENSSL_FIPS ++ ++/* Due to the need to use EVP in FIPS mode we can't reimplement digests but ++ * we can ensure the number of blocks processed is equal for all cases ++ * by digesting additional data. ++ */ ++ ++void tls_fips_digest_extra( ++ const EVP_CIPHER_CTX *cipher_ctx, const EVP_MD *hash, HMAC_CTX *hctx, ++ const unsigned char *data, size_t data_len, size_t orig_len) ++ { ++ size_t block_size, digest_pad, blocks_data, blocks_orig; ++ if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE) ++ return; ++ block_size = EVP_MD_block_size(hash); ++ /* We are in FIPS mode if we get this far so we know we have only SHA* ++ * digests and TLS to deal with. ++ * Minimum digest padding length is 17 for SHA384/SHA512 and 9 ++ * otherwise. ++ * Additional header is 13 bytes. To get the number of digest blocks ++ * processed round up the amount of data plus padding to the nearest ++ * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise. ++ * So we have: ++ * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size ++ * equivalently: ++ * blocks = (payload_len + digest_pad + 12)/block_size + 1 ++ * HMAC adds a constant overhead. ++ * We're ultimately only interested in differences so this becomes ++ * blocks = (payload_len + 29)/128 ++ * for SHA384/SHA512 and ++ * blocks = (payload_len + 21)/64 ++ * otherwise. ++ */ ++ digest_pad = block_size == 64 ? 21 : 29; ++ blocks_orig = (orig_len + digest_pad)/block_size; ++ blocks_data = (data_len + digest_pad)/block_size; ++ /* MAC enough blocks to make up the difference between the original ++ * and actual lengths plus one extra block to ensure this is never a ++ * no op. The "data" pointer should always have enough space to ++ * perform this operation as it is large enough for a maximum ++ * length TLS buffer. ++ */ ++ HMAC_Update(hctx, data, ++ (blocks_orig - blocks_data + 1) * block_size); ++ } ++#endif +Index: openssl098-0.9.8o/ssl/s3_enc.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/s3_enc.c 2014-06-17 15:43:29.000000000 +0200 ++++ openssl098-0.9.8o/ssl/s3_enc.c 2014-06-18 11:58:59.124269880 +0200 +@@ -434,12 +434,21 @@ + s->s3->tmp.key_block_length=0; + } + ++/* ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. ++ * ++ * Returns: ++ * 0: (in non-constant time) if the record is publically invalid (i.e. too ++ * short etc). ++ * 1: if the record's padding is valid / the encryption was successful. ++ * -1: if the record's padding is invalid or, if sending, an internal error ++ * occured. ++ */ + int ssl3_enc(SSL *s, int send) + { + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; +- int bs,i; ++ int bs,i,mac_size=0; + const EVP_CIPHER *enc; + + if (send) +@@ -490,32 +499,17 @@ + if (!send) + { + if (l == 0 || l%bs != 0) +- { +- SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); +- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); + return 0; +- } + /* otherwise, rec->length >= bs */ + } + + EVP_Cipher(ds,rec->data,rec->input,l); + ++ if (s->read_hash != NULL) ++ mac_size = EVP_MD_size(s->read_hash); ++ + if ((bs != 1) && !send) +- { +- i=rec->data[l-1]+1; +- /* SSL 3.0 bounds the number of padding bytes by the block size; +- * padding bytes (except the last one) are arbitrary */ +- if (i > bs) +- { +- /* Incorrect padding. SSLerr() and ssl3_alert are done +- * by caller: we don't want to reveal whether this is +- * a decryption error or a MAC verification failure +- * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ +- return -1; +- } +- /* now i <= bs <= rec->length */ +- rec->length-=i; +- } ++ return ssl3_cbc_remove_padding(s, rec, bs, mac_size); + } + return(1); + } +@@ -592,7 +586,7 @@ + EVP_MD_CTX md_ctx; + const EVP_MD *hash; + unsigned char *p,rec_char; +- unsigned int md_size; ++ size_t md_size, orig_len; + int npad; + + if (send) +@@ -613,28 +607,72 @@ + md_size=EVP_MD_size(hash); + npad=(48/md_size)*md_size; + +- /* Chop the digest off the end :-) */ +- EVP_MD_CTX_init(&md_ctx); +- +- EVP_DigestInit_ex( &md_ctx,hash, NULL); +- EVP_DigestUpdate(&md_ctx,mac_sec,md_size); +- EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad); +- EVP_DigestUpdate(&md_ctx,seq,8); +- rec_char=rec->type; +- EVP_DigestUpdate(&md_ctx,&rec_char,1); +- p=md; +- s2n(rec->length,p); +- EVP_DigestUpdate(&md_ctx,md,2); +- EVP_DigestUpdate(&md_ctx,rec->input,rec->length); +- EVP_DigestFinal_ex( &md_ctx,md,NULL); +- +- EVP_DigestInit_ex( &md_ctx,hash, NULL); +- EVP_DigestUpdate(&md_ctx,mac_sec,md_size); +- EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad); +- EVP_DigestUpdate(&md_ctx,md,md_size); +- EVP_DigestFinal_ex( &md_ctx,md,&md_size); ++ /* kludge: ssl3_cbc_remove_padding passes padding length in rec->type */ ++ orig_len = rec->length+md_size+((unsigned int)rec->type>>8); ++ rec->type &= 0xff; ++ ++ if (!send && ++ EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && ++ ssl3_cbc_record_digest_supported(hash)) ++ { ++ /* This is a CBC-encrypted record. We must avoid leaking any ++ * timing-side channel information about how many blocks of ++ * data we are hashing because that gives an attacker a ++ * timing-oracle. */ ++ ++ /* npad is, at most, 48 bytes and that's with MD5: ++ * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75. ++ * ++ * With SHA-1 (the largest hash speced for SSLv3) the hash size ++ * goes up 4, but npad goes down by 8, resulting in a smaller ++ * total size. */ ++ unsigned char header[75]; ++ unsigned j = 0; ++ memcpy(header+j, mac_sec, md_size); ++ j += md_size; ++ memcpy(header+j, ssl3_pad_1, npad); ++ j += npad; ++ memcpy(header+j, seq, 8); ++ j += 8; ++ header[j++] = rec->type; ++ header[j++] = rec->length >> 8; ++ header[j++] = rec->length & 0xff; ++ ++ ssl3_cbc_digest_record( ++ hash, ++ md, &md_size, ++ header, rec->input, ++ rec->length + md_size, orig_len, ++ mac_sec, md_size, ++ 1 /* is SSLv3 */); ++ } ++ else ++ { ++ unsigned int md_size_u; ++ /* Chop the digest off the end :-) */ ++ EVP_MD_CTX_init(&md_ctx); ++ ++ EVP_DigestInit_ex( &md_ctx,hash, NULL); ++ EVP_DigestUpdate(&md_ctx,mac_sec,md_size); ++ EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad); ++ EVP_DigestUpdate(&md_ctx,seq,8); ++ rec_char=rec->type; ++ EVP_DigestUpdate(&md_ctx,&rec_char,1); ++ p=md; ++ s2n(rec->length,p); ++ EVP_DigestUpdate(&md_ctx,md,2); ++ EVP_DigestUpdate(&md_ctx,rec->input,rec->length); ++ EVP_DigestFinal_ex( &md_ctx,md,NULL); ++ ++ EVP_DigestInit_ex( &md_ctx,hash, NULL); ++ EVP_DigestUpdate(&md_ctx,mac_sec,md_size); ++ EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad); ++ EVP_DigestUpdate(&md_ctx,md,md_size); ++ EVP_DigestFinal_ex( &md_ctx,md,&md_size_u); ++ md_size = md_size_u; + +- EVP_MD_CTX_cleanup(&md_ctx); ++ EVP_MD_CTX_cleanup(&md_ctx); ++ } + + ssl3_record_sequence_update(seq); + return(md_size); +Index: openssl098-0.9.8o/ssl/s3_pkt.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/s3_pkt.c 2014-06-18 11:44:15.000000000 +0200 ++++ openssl098-0.9.8o/ssl/s3_pkt.c 2014-06-18 11:58:59.124269880 +0200 +@@ -246,11 +246,8 @@ + unsigned char *p; + unsigned char md[EVP_MAX_MD_SIZE]; + short version; +- unsigned int mac_size; +- int clear=0; ++ unsigned mac_size, orig_len; + size_t extra; +- int decryption_failed_or_bad_record_mac = 0; +- unsigned char *mac = NULL; + + rr= &(s->s3->rrec); + sess=s->session; +@@ -356,17 +353,15 @@ + rr->data=rr->input; + + enc_err = s->method->ssl3_enc->enc(s,0); +- if (enc_err <= 0) ++ /* enc_err is: ++ * 0: (in non-constant time) if the record is publically invalid. ++ * 1: if the padding is valid ++ * -1: if the padding is invalid */ ++ if (enc_err == 0) + { +- if (enc_err == 0) +- /* SSLerr() and ssl3_send_alert() have been called */ +- goto err; +- +- /* Otherwise enc_err == -1, which indicates bad padding +- * (rec->length has not been changed in this case). +- * To minimize information leaked via timing, we will perform +- * the MAC computation anyway. */ +- decryption_failed_or_bad_record_mac = 1; ++ al=SSL_AD_DECRYPTION_FAILED; ++ SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); ++ goto f_err; + } + + #ifdef TLS_DEBUG +@@ -376,51 +371,62 @@ + #endif + + /* r->length is now the compressed data plus mac */ +- if ( (sess == NULL) || +- (s->enc_read_ctx == NULL) || +- (s->read_hash == NULL)) +- clear=1; +- +- if (!clear) +- { ++ if ((sess != NULL) && ++ (s->enc_read_ctx != NULL) && ++ (s->read_hash != NULL)) ++ { ++ /* s->read_hash != NULL => mac_size != -1 */ ++ unsigned char *mac = NULL; ++ unsigned char mac_tmp[EVP_MAX_MD_SIZE]; + mac_size=EVP_MD_size(s->read_hash); ++ OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); + +- if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) ++ /* kludge: *_cbc_remove_padding passes padding length in rr->type */ ++ orig_len = rr->length+((unsigned int)rr->type>>8); ++ ++ /* orig_len is the length of the record before any padding was ++ * removed. This is public information, as is the MAC in use, ++ * therefore we can safely process the record in a different ++ * amount of time if it's too short to possibly contain a MAC. ++ */ ++ if (orig_len < mac_size || ++ /* CBC records must have a padding length byte too. */ ++ (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && ++ orig_len < mac_size+1)) + { +-#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ +- al=SSL_AD_RECORD_OVERFLOW; +- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); ++ al=SSL_AD_DECODE_ERROR; ++ SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); + goto f_err; +-#else +- decryption_failed_or_bad_record_mac = 1; +-#endif + } +- /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ +- if (rr->length >= mac_size) ++ ++ if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) + { ++ /* We update the length so that the TLS header bytes ++ * can be constructed correctly but we need to extract ++ * the MAC in constant time from within the record, ++ * without leaking the contents of the padding bytes. ++ * */ ++ mac = mac_tmp; ++ ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); + rr->length -= mac_size; +- mac = &rr->data[rr->length]; + } + else + { +- /* record (minus padding) is too short to contain a MAC */ +-#if 0 /* OK only for stream ciphers */ +- al=SSL_AD_DECODE_ERROR; +- SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); +- goto f_err; +-#else +- decryption_failed_or_bad_record_mac = 1; +- rr->length = 0; +-#endif +- } +- i=s->method->ssl3_enc->mac(s,md,0); +- if (mac == NULL || memcmp(md, mac, mac_size) != 0) +- { +- decryption_failed_or_bad_record_mac = 1; ++ /* In this case there's no padding, so |orig_len| ++ * equals |rec->length| and we checked that there's ++ * enough bytes for |mac_size| above. */ ++ rr->length -= mac_size; ++ mac = &rr->data[rr->length]; + } ++ ++ i=s->method->ssl3_enc->mac(s,md,0 /* not send */); ++ if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) ++ enc_err = -1; ++ if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) ++ enc_err = -1; + } + +- if (decryption_failed_or_bad_record_mac) ++ if (enc_err < 0) + { + /* A separate 'decryption_failed' alert was introduced with TLS 1.0, + * SSL 3.0 only has 'bad_record_mac'. But unless a decryption +Index: openssl098-0.9.8o/ssl/ssl_err.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/ssl_err.c 2014-06-17 15:43:29.000000000 +0200 ++++ openssl098-0.9.8o/ssl/ssl_err.c 2014-06-18 11:58:59.124269880 +0200 +@@ -217,6 +217,7 @@ + {ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION), "SSL_GET_NEW_SESSION"}, + {ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "SSL_GET_PREV_SESSION"}, + {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT), "SSL_GET_SERVER_SEND_CERT"}, ++{ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY), "SSL_GET_SERVER_SEND_PKEY"}, + {ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "SSL_GET_SIGN_PKEY"}, + {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "SSL_INIT_WBIO_BUFFER"}, + {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"}, +Index: openssl098-0.9.8o/ssl/ssl.h +=================================================================== +--- openssl098-0.9.8o.orig/ssl/ssl.h 2014-06-17 15:43:29.000000000 +0200 ++++ openssl098-0.9.8o/ssl/ssl.h 2014-06-18 11:58:59.124269880 +0200 +@@ -1819,6 +1819,7 @@ + #define SSL_F_SSL_GET_NEW_SESSION 181 + #define SSL_F_SSL_GET_PREV_SESSION 217 + #define SSL_F_SSL_GET_SERVER_SEND_CERT 182 ++#define SSL_F_SSL_GET_SERVER_SEND_PKEY 317 + #define SSL_F_SSL_GET_SIGN_PKEY 183 + #define SSL_F_SSL_INIT_WBIO_BUFFER 184 + #define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 +Index: openssl098-0.9.8o/ssl/ssl_lib.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/ssl_lib.c 2014-06-17 15:43:29.000000000 +0200 ++++ openssl098-0.9.8o/ssl/ssl_lib.c 2014-06-18 11:58:59.128269880 +0200 +@@ -1997,7 +1997,7 @@ + } + else /* if (kalg & SSL_aNULL) */ + { +- SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR); ++ SSLerr(SSL_F_SSL_GET_SERVER_SEND_PKEY,ERR_R_INTERNAL_ERROR); + return(NULL); + } + if (c->pkeys[i].x509 == NULL) return(NULL); +Index: openssl098-0.9.8o/ssl/ssl_locl.h +=================================================================== +--- openssl098-0.9.8o.orig/ssl/ssl_locl.h 2009-12-08 14:15:37.000000000 +0100 ++++ openssl098-0.9.8o/ssl/ssl_locl.h 2014-06-18 11:58:59.128269880 +0200 +@@ -189,6 +189,15 @@ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + ++#define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>48)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>40)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>32)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>24)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>16)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ ++ *((c)++)=(unsigned char)(((l) )&0xff)) ++ + #define n2l6(c,l) (l =((BN_ULLONG)(*((c)++)))<<40, \ + l|=((BN_ULLONG)(*((c)++)))<<32, \ + l|=((BN_ULLONG)(*((c)++)))<<24, \ +@@ -999,5 +1008,33 @@ + int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, + int *al); + #endif ++/* s3_cbc.c */ ++void ssl3_cbc_copy_mac(unsigned char* out, ++ const SSL3_RECORD *rec, ++ unsigned md_size,unsigned orig_len); ++int ssl3_cbc_remove_padding(const SSL* s, ++ SSL3_RECORD *rec, ++ unsigned block_size, ++ unsigned mac_size); ++int tls1_cbc_remove_padding(const SSL* s, ++ SSL3_RECORD *rec, ++ unsigned block_size, ++ unsigned mac_size); ++char ssl3_cbc_record_digest_supported(const EVP_MD *hash); ++void ssl3_cbc_digest_record( ++ const EVP_MD *hash, ++ unsigned char* md_out, ++ size_t* md_out_size, ++ const unsigned char header[13], ++ const unsigned char *data, ++ size_t data_plus_mac_size, ++ size_t data_plus_mac_plus_padding_size, ++ const unsigned char *mac_secret, ++ unsigned mac_secret_length, ++ char is_sslv3); ++ ++void tls_fips_digest_extra( ++ const EVP_CIPHER_CTX *cipher_ctx, const EVP_MD *hash, HMAC_CTX *hctx, ++ const unsigned char *data, size_t data_len, size_t orig_len); + + #endif +Index: openssl098-0.9.8o/ssl/ssltest.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/ssltest.c 2009-01-07 11:48:23.000000000 +0100 ++++ openssl098-0.9.8o/ssl/ssltest.c 2014-06-18 11:58:59.128269880 +0200 +@@ -735,7 +735,13 @@ + meth=SSLv23_method(); + #else + #ifdef OPENSSL_NO_SSL2 +- meth=SSLv3_method(); ++ if (tls1) ++ meth=TLSv1_method(); ++ else ++ if (ssl3) ++ meth=SSLv3_method(); ++ else ++ meth=SSLv23_method(); + #else + meth=SSLv2_method(); + #endif +Index: openssl098-0.9.8o/ssl/t1_enc.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/t1_enc.c 2009-04-19 20:08:12.000000000 +0200 ++++ openssl098-0.9.8o/ssl/t1_enc.c 2014-06-18 11:58:59.128269880 +0200 +@@ -530,12 +530,21 @@ + return(0); + } + ++/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. ++ * ++ * Returns: ++ * 0: (in non-constant time) if the record is publically invalid (i.e. too ++ * short etc). ++ * 1: if the record's padding is valid / the encryption was successful. ++ * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, ++ * an internal error occured. ++ */ + int tls1_enc(SSL *s, int send) + { + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; +- int bs,i,ii,j,k,n=0; ++ int bs,i,ii,j,k,n=0,pad=0,ret,mac_size=0; + const EVP_CIPHER *enc; + + if (send) +@@ -565,11 +574,11 @@ + printf("tls1_enc(%d)\n", send); + #endif /* KSSL_DEBUG */ + +- if ((s->session == NULL) || (ds == NULL) || +- (enc == NULL)) ++ if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) + { + memmove(rec->data,rec->input,rec->length); + rec->input=rec->data; ++ ret = 1; + } + else + { +@@ -597,14 +606,13 @@ + + #ifdef KSSL_DEBUG + { +- unsigned long ui; ++ unsigned long ui; + printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", +- (void *)ds,rec->data,rec->input,l); +- printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n", +- ds->buf_len, ds->cipher->key_len, +- (unsigned long)DES_KEY_SZ, +- (unsigned long)DES_SCHEDULE_SZ, +- ds->cipher->iv_len); ++ ds,rec->data,rec->input,l); ++ printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", ++ ds->buf_len, ds->cipher->key_len, ++ DES_KEY_SZ, DES_SCHEDULE_SZ, ++ ds->cipher->iv_len); + printf("\t\tIV: "); + for (i=0; icipher->iv_len; i++) printf("%02X", ds->iv[i]); + printf("\n"); +@@ -617,11 +625,7 @@ + if (!send) + { + if (l == 0 || l%bs != 0) +- { +- SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); +- ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); + return 0; +- } + } + + EVP_Cipher(ds,rec->data,rec->input,l); +@@ -635,49 +639,15 @@ + } + #endif /* KSSL_DEBUG */ + ++ ret = 1; ++ if (s->read_hash != NULL) ++ mac_size = EVP_MD_size(s->read_hash); + if ((bs != 1) && !send) +- { +- ii=i=rec->data[l-1]; /* padding_length */ +- i++; +- /* NB: if compression is in operation the first packet +- * may not be of even length so the padding bug check +- * cannot be performed. This bug workaround has been +- * around since SSLeay so hopefully it is either fixed +- * now or no buggy implementation supports compression +- * [steve] +- */ +- if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) +- && !s->expand) +- { +- /* First packet is even in size, so check */ +- if ((memcmp(s->s3->read_sequence, +- "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) +- s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; +- if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) +- i--; +- } +- /* TLS 1.0 does not bound the number of padding bytes by the block size. +- * All of them must have value 'padding_length'. */ +- if (i > (int)rec->length) +- { +- /* Incorrect padding. SSLerr() and ssl3_alert are done +- * by caller: we don't want to reveal whether this is +- * a decryption error or a MAC verification failure +- * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ +- return -1; +- } +- for (j=(int)(l-i); j<(int)l; j++) +- { +- if (rec->data[j] != ii) +- { +- /* Incorrect padding */ +- return -1; +- } +- } +- rec->length-=i; +- } ++ ret = tls1_cbc_remove_padding(s, rec, bs, mac_size); ++ if (pad && !send) ++ rec->length -= pad; + } +- return(1); ++ return ret; + } + + int tls1_cert_verify_mac(SSL *s, EVP_MD_CTX *in_ctx, unsigned char *out) +@@ -725,10 +695,10 @@ + SSL3_RECORD *rec; + unsigned char *mac_sec,*seq; + const EVP_MD *hash; +- unsigned int md_size; ++ size_t md_size, orig_len; + int i; + HMAC_CTX hmac; +- unsigned char buf[5]; ++ unsigned char header[13]; + + if (send) + { +@@ -747,20 +717,6 @@ + + md_size=EVP_MD_size(hash); + +- buf[0]=rec->type; +- if (ssl->version == DTLS1_VERSION && ssl->client_version == DTLS1_BAD_VER) +- { +- buf[1]=TLS1_VERSION_MAJOR; +- buf[2]=TLS1_VERSION_MINOR; +- } +- else { +- buf[1]=(unsigned char)(ssl->version>>8); +- buf[2]=(unsigned char)(ssl->version); +- } +- +- buf[3]=rec->length>>8; +- buf[4]=rec->length&0xff; +- + /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ + HMAC_CTX_init(&hmac); + HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL); +@@ -772,16 +728,57 @@ + s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p); + memcpy (p,&seq[2],6); + +- HMAC_Update(&hmac,dtlsseq,8); ++ memcpy(header, dtlsseq, 8); + } + else +- HMAC_Update(&hmac,seq,8); ++ memcpy(header, seq, 8); + +- HMAC_Update(&hmac,buf,5); +- HMAC_Update(&hmac,rec->input,rec->length); +- HMAC_Final(&hmac,md,&md_size); +- HMAC_CTX_cleanup(&hmac); ++ /* kludge: tls1_cbc_remove_padding passes padding length in rec->type */ ++ orig_len = rec->length+md_size+((unsigned int)rec->type>>8); ++ rec->type &= 0xff; ++ ++ header[8]=rec->type; ++ header[9]=(unsigned char)(ssl->version>>8); ++ header[10]=(unsigned char)(ssl->version); ++ header[11]=(rec->length)>>8; ++ header[12]=(rec->length)&0xff; ++ ++ if (!send && ++ EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && ++ ssl3_cbc_record_digest_supported(hash)) ++ { ++ /* This is a CBC-encrypted record. We must avoid leaking any ++ * timing-side channel information about how many blocks of ++ * data we are hashing because that gives an attacker a ++ * timing-oracle. */ ++ ssl3_cbc_digest_record( ++ hash, ++ md, &md_size, ++ header, rec->input, ++ rec->length + md_size, orig_len, ++ ssl->s3->read_mac_secret, ++ EVP_MD_size(ssl->read_hash), ++ 0 /* not SSLv3 */); ++ } ++ else ++ { ++ unsigned mds; + ++ HMAC_Update(&hmac,header,sizeof(header)); ++ HMAC_Update(&hmac,rec->input,rec->length); ++ HMAC_Final(&hmac,md,&mds); ++ md_size = mds; ++#ifdef OPENSSL_FIPS ++ if (!send && FIPS_mode()) ++ tls_fips_digest_extra( ++ ssl->enc_read_ctx, ++ hash, ++ &hmac, rec->input, ++ rec->length, rec->orig_len); ++#endif ++ } ++ ++ HMAC_CTX_cleanup(&hmac); + #ifdef TLS_DEBUG + printf("sec="); + {unsigned int z; for (z=0; z +Date: Tue May 13 18:48:31 2014 +0100 + + Fix for CVE-2014-0195 + + A buffer overrun attack can be triggered by sending invalid DTLS fragments + to an OpenSSL DTLS client or server. This is potentially exploitable to + run arbitrary code on a vulnerable client or server. + + Fixed by adding consistency check for DTLS fragments. + + Thanks to Jüri Aedla for reporting this issue. + +Index: openssl098-0.9.8o/ssl/d1_both.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/d1_both.c 2014-06-18 12:01:53.000000000 +0200 ++++ openssl098-0.9.8o/ssl/d1_both.c 2014-06-18 12:08:56.368285172 +0200 +@@ -633,7 +633,16 @@ + frag->msg_header.frag_off = 0; + } + else ++ { + frag = (hm_fragment*) item->data; ++ if (frag->msg_header.msg_len != msg_hdr->msg_len) ++ { ++ item = NULL; ++ frag = NULL; ++ goto err; ++ } ++ } ++ + + /* If message is already reassembled, this must be a + * retransmit and can be dropped. diff -Nru openssl098-0.9.8o/debian/patches/CVE-2014-0221.patch openssl098-0.9.8o/debian/patches/CVE-2014-0221.patch --- openssl098-0.9.8o/debian/patches/CVE-2014-0221.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssl098-0.9.8o/debian/patches/CVE-2014-0221.patch 2014-06-19 09:49:58.000000000 +0200 @@ -0,0 +1,33 @@ +commit d30e582446b027868cdabd0994681643682045a4 +Author: Dr. Stephen Henson +Date: Fri May 16 13:00:45 2014 +0100 + + Fix CVE-2014-0221 + + Unnecessary recursion when receiving a DTLS hello request can be used to + crash a DTLS client. Fixed by handling DTLS hello request without recursion. + + Thanks to Imre Rad (Search-Lab Ltd.) for discovering this issue. + +Index: openssl098-0.9.8o/ssl/d1_both.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/d1_both.c 2014-06-18 12:08:56.368285172 +0200 ++++ openssl098-0.9.8o/ssl/d1_both.c 2014-06-18 12:10:50.592288097 +0200 +@@ -799,6 +799,7 @@ + int i,al; + struct hm_header_st msg_hdr; + ++ redo: + /* see if we have the required fragment already */ + if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) + { +@@ -849,8 +850,7 @@ + s->msg_callback_arg); + + s->init_num = 0; +- return dtls1_get_message_fragment(s, st1, stn, +- max, ok); ++ goto redo; + } + else /* Incorrectly formated Hello request */ + { diff -Nru openssl098-0.9.8o/debian/patches/CVE-2014-0224-1.patch openssl098-0.9.8o/debian/patches/CVE-2014-0224-1.patch --- openssl098-0.9.8o/debian/patches/CVE-2014-0224-1.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssl098-0.9.8o/debian/patches/CVE-2014-0224-1.patch 2014-06-19 09:49:58.000000000 +0200 @@ -0,0 +1,79 @@ +Backport of: + +commit eaa71076511eab5e84ed36ddecbfc6cc20a48952 +Author: Dr. Stephen Henson +Date: Fri May 16 12:49:48 2014 +0100 + + Fix for CVE-2014-0224 + + Only accept change cipher spec when it is expected instead of at any + time. This prevents premature setting of session keys before the master + secret is determined which an attacker could use as a MITM attack. + + Thanks to KIKUCHI Masashi (Lepidum Co. Ltd.) for reporting this issue + and providing the initial fix this patch is based on. + +Index: openssl098-0.9.8o/ssl/s3_clnt.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/s3_clnt.c 2014-06-18 12:00:43.000000000 +0200 ++++ openssl098-0.9.8o/ssl/s3_clnt.c 2014-06-18 12:12:24.208290494 +0200 +@@ -483,6 +483,7 @@ + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_CR_FINISHED_B: + ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, + SSL3_ST_CR_FINISHED_B); + if (ret <= 0) goto end; +Index: openssl098-0.9.8o/ssl/s3_pkt.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/s3_pkt.c 2014-06-18 12:00:43.000000000 +0200 ++++ openssl098-0.9.8o/ssl/s3_pkt.c 2014-06-18 12:12:24.208290494 +0200 +@@ -1149,6 +1149,15 @@ + goto f_err; + } + ++ if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) ++ { ++ al=SSL_AD_UNEXPECTED_MESSAGE; ++ SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY); ++ goto f_err; ++ } ++ ++ s->s3->flags &= ~SSL3_FLAGS_CCS_OK; ++ + rr->length=0; + + if (s->msg_callback) +Index: openssl098-0.9.8o/ssl/s3_srvr.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/s3_srvr.c 2014-06-18 12:00:43.000000000 +0200 ++++ openssl098-0.9.8o/ssl/s3_srvr.c 2014-06-18 12:12:24.208290494 +0200 +@@ -523,6 +523,7 @@ + case SSL3_ST_SR_CERT_VRFY_A: + case SSL3_ST_SR_CERT_VRFY_B: + ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + /* we should decide if we expected this one */ + ret=ssl3_get_cert_verify(s); + if (ret <= 0) goto end; +@@ -533,6 +534,7 @@ + + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_SR_FINISHED_B: ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, + SSL3_ST_SR_FINISHED_B); + if (ret <= 0) goto end; +Index: openssl098-0.9.8o/ssl/ssl3.h +=================================================================== +--- openssl098-0.9.8o.orig/ssl/ssl3.h 2014-06-18 12:00:43.000000000 +0200 ++++ openssl098-0.9.8o/ssl/ssl3.h 2014-06-18 12:12:24.208290494 +0200 +@@ -333,6 +333,7 @@ + #define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 + #define SSL3_FLAGS_POP_BUFFER 0x0004 + #define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 ++#define SSL3_FLAGS_CCS_OK 0x0080 + + /* SSL3_FLAGS_SGC_RESTART_DONE is set when we + * restart a handshake because of MS SGC and so prevents us diff -Nru openssl098-0.9.8o/debian/patches/CVE-2014-0224-2.patch openssl098-0.9.8o/debian/patches/CVE-2014-0224-2.patch --- openssl098-0.9.8o/debian/patches/CVE-2014-0224-2.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssl098-0.9.8o/debian/patches/CVE-2014-0224-2.patch 2014-06-19 09:49:58.000000000 +0200 @@ -0,0 +1,22 @@ +commit a5852a6db4b36f91d6254b2d8757f125e6e8e5cb +Author: Dr. Stephen Henson +Date: Fri May 16 12:55:16 2014 +0100 + + Additional CVE-2014-0224 protection. + + Return a fatal error if an attempt is made to use a zero length + master secret. + +Index: openssl098-0.9.8o/ssl/s3_pkt.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/s3_pkt.c 2014-06-18 12:12:24.208290494 +0200 ++++ openssl098-0.9.8o/ssl/s3_pkt.c 2014-06-18 12:13:38.892292406 +0200 +@@ -1289,7 +1289,7 @@ + + if (s->s3->tmp.key_block == NULL) + { +- if (s->session == NULL) ++ if (s->session == NULL || s->session->master_key_length == 0) + { + /* might happen if dtls1_read_bytes() calls this */ + SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY); diff -Nru openssl098-0.9.8o/debian/patches/CVE-2014-0224-3.patch openssl098-0.9.8o/debian/patches/CVE-2014-0224-3.patch --- openssl098-0.9.8o/debian/patches/CVE-2014-0224-3.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssl098-0.9.8o/debian/patches/CVE-2014-0224-3.patch 2014-06-19 09:49:58.000000000 +0200 @@ -0,0 +1,12 @@ +Index: openssl098-0.9.8o/ssl/s3_clnt.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/s3_clnt.c 2014-06-18 12:12:24.208290494 +0200 ++++ openssl098-0.9.8o/ssl/s3_clnt.c 2014-06-18 12:14:34.000293817 +0200 +@@ -770,6 +770,7 @@ + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + goto f_err; + } ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + s->hit=1; + } + else /* a miss or crap from the other end */ diff -Nru openssl098-0.9.8o/debian/patches/CVE-2014-0224-regression2.patch openssl098-0.9.8o/debian/patches/CVE-2014-0224-regression2.patch --- openssl098-0.9.8o/debian/patches/CVE-2014-0224-regression2.patch 1970-01-01 01:00:00.000000000 +0100 +++ openssl098-0.9.8o/debian/patches/CVE-2014-0224-regression2.patch 2014-06-23 10:54:22.000000000 +0200 @@ -0,0 +1,27 @@ +From 70d923fb0359ed68e59b8c59d1687ebff6f8d952 Mon Sep 17 00:00:00 2001 +From: "Dr. Stephen Henson" +Date: Sat, 14 Jun 2014 22:24:08 +0100 +Subject: [PATCH] Accept CCS after sending finished. + +Allow CCS after finished has been sent by client: at this point +keys have been correctly set up so it is OK to accept CCS from +server. Without this renegotiation can sometimes fail. + +PR#3400 +(cherry picked from commit 99cd6a91fcb0931feaebbb4832681d40a66fad41) +--- + ssl/s3_clnt.c | 1 + + 1 file changed, 1 insertion(+) + +Index: openssl098-0.9.8o/ssl/s3_clnt.c +=================================================================== +--- openssl098-0.9.8o.orig/ssl/s3_clnt.c 2014-06-23 10:47:04.000000000 +0200 ++++ openssl098-0.9.8o/ssl/s3_clnt.c 2014-06-23 10:47:50.149774986 +0200 +@@ -434,6 +434,7 @@ + s->method->ssl3_enc->client_finished_label, + s->method->ssl3_enc->client_finished_label_len); + if (ret <= 0) goto end; ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + s->state=SSL3_ST_CW_FLUSH; + + /* clear flags */ diff -Nru openssl098-0.9.8o/debian/patches/series openssl098-0.9.8o/debian/patches/series --- openssl098-0.9.8o/debian/patches/series 2012-04-24 17:06:41.000000000 +0200 +++ openssl098-0.9.8o/debian/patches/series 2014-06-23 10:47:24.000000000 +0200 @@ -38,3 +38,14 @@ CVE-2012-2110.patch CVE-2012-2110b.patch CVE-2012-2131.patch +CVE-2012-0884.patch +CVE-2012-0884-extra.patch +CVE-2012-2333.patch +CVE-2013-0166.patch +CVE-2013-0169.patch +CVE-2014-0195.patch +CVE-2014-0221.patch +CVE-2014-0224-1.patch +CVE-2014-0224-2.patch +CVE-2014-0224-3.patch +CVE-2014-0224-regression2.patch