int RSA_message_index_PKCS1_type_2(const uint8_t *from, size_t from_len, size_t *out_index) { size_t i; int first_byte_is_zero, second_byte_is_two, looking_for_index; int valid_index, zero_index = 0; /* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography * Standard", section 7.2.2. */ if (from_len < RSA_PKCS1_PADDING_SIZE) { return 0; } first_byte_is_zero = constant_time_byte_eq(from[0], 0); second_byte_is_two = constant_time_byte_eq(from[1], 2); looking_for_index = 1; for (i = 2; i < from_len; i++) { int equals0 = constant_time_byte_eq(from[i], 0); zero_index = constant_time_select(looking_for_index & equals0, i, zero_index); looking_for_index = constant_time_select(equals0, 0, looking_for_index); } /* The input must begin with 00 02. */ valid_index = first_byte_is_zero; valid_index &= second_byte_is_two; /* We must have found the end of PS. */ valid_index &= ~looking_for_index; /* PS must be at least 8 bytes long, and it starts two bytes into |from|. */ valid_index &= constant_time_le(2 + 8, zero_index); /* Skip the zero byte. */ *out_index = zero_index + 1; return valid_index; }
int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned to_len, const uint8_t *from, unsigned from_len) { if (from_len == 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); return -1; } /* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography * Standard", section 7.2.2. */ if (from_len < RSA_PKCS1_PADDING_SIZE) { /* |from| is zero-padded to the size of the RSA modulus, a public value, so * this can be rejected in non-constant time. */ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); return -1; } unsigned first_byte_is_zero = constant_time_eq(from[0], 0); unsigned second_byte_is_two = constant_time_eq(from[1], 2); unsigned i, zero_index = 0, looking_for_index = ~0u; for (i = 2; i < from_len; i++) { unsigned equals0 = constant_time_is_zero(from[i]); zero_index = constant_time_select(looking_for_index & equals0, (unsigned)i, zero_index); looking_for_index = constant_time_select(equals0, 0, looking_for_index); } /* The input must begin with 00 02. */ unsigned valid_index = first_byte_is_zero; valid_index &= second_byte_is_two; /* We must have found the end of PS. */ valid_index &= ~looking_for_index; /* PS must be at least 8 bytes long, and it starts two bytes into |from|. */ valid_index &= constant_time_ge(zero_index, 2 + 8); /* Skip the zero byte. */ zero_index++; /* NOTE: Although this logic attempts to be constant time, the API contracts * of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it * impossible to completely avoid Bleichenbacher's attack. Consumers should * use |RSA_unpad_key_pkcs1|. */ if (!valid_index) { OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); return -1; } const unsigned msg_len = from_len - zero_index; if (msg_len > to_len) { /* This shouldn't happen because this function is always called with * |to_len| as the key size and |from_len| is bounded by the key size. */ OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); return -1; } if (msg_len > INT_MAX) { OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); return -1; } memcpy(to, &from[zero_index], msg_len); return (int)msg_len; }
int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen, const uint8_t *from, unsigned flen, const uint8_t *param, unsigned plen, const EVP_MD *md, const EVP_MD *mgf1md) { unsigned i, dblen, mlen = -1, mdlen; const uint8_t *maskeddb, *maskedseed; uint8_t *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE]; int bad, looking_for_one_byte, one_index = 0; if (md == NULL) { md = EVP_sha1(); } if (mgf1md == NULL) { mgf1md = md; } mdlen = EVP_MD_size(md); /* The encoded message is one byte smaller than the modulus to ensure that it * doesn't end up greater than the modulus. Thus there's an extra "+1" here * compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2. */ if (flen < 1 + 2*mdlen + 1) { /* 'flen' is the length of the modulus, i.e. does not depend on the * particular ciphertext. */ goto decoding_err; } dblen = flen - mdlen - 1; db = OPENSSL_malloc(dblen); if (db == NULL) { OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1, ERR_R_MALLOC_FAILURE); goto err; } maskedseed = from + 1; maskeddb = from + 1 + mdlen; if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) { goto err; } for (i = 0; i < mdlen; i++) { seed[i] ^= maskedseed[i]; } if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) { goto err; } for (i = 0; i < dblen; i++) { db[i] ^= maskeddb[i]; } if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL)) { goto err; } bad = CRYPTO_memcmp(db, phash, mdlen); bad |= from[0]; looking_for_one_byte = 1; for (i = mdlen; i < dblen; i++) { int equals1 = constant_time_byte_eq(db[i], 1); int equals0 = constant_time_byte_eq(db[i], 0); one_index = constant_time_select(looking_for_one_byte & equals1, i, one_index); looking_for_one_byte = constant_time_select(equals1, 0, looking_for_one_byte); bad |= looking_for_one_byte & ~equals0; } bad |= looking_for_one_byte; if (bad) { goto decoding_err; } one_index++; mlen = dblen - one_index; if (tlen < mlen) { OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1, RSA_R_DATA_TOO_LARGE); mlen = -1; } else { memcpy(to, db + one_index, mlen); } OPENSSL_free(db); return mlen; decoding_err: /* to avoid chosen ciphertext attacks, the error message should not reveal * which kind of decoding error happened */ OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1, RSA_R_OAEP_DECODING_ERROR); err: if (db != NULL) { OPENSSL_free(db); } return -1; }
void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size, const uint8_t *in, unsigned in_len, unsigned orig_len) { #if defined(CBC_MAC_ROTATE_IN_PLACE) uint8_t rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; uint8_t *rotated_mac; #else uint8_t rotated_mac[EVP_MAX_MD_SIZE]; #endif /* mac_end is the index of |in| just after the end of the MAC. */ unsigned mac_end = in_len; 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 rotate_offset; assert(orig_len >= in_len); assert(in_len >= md_size); 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); } /* Ideally the next statement would be: * * rotate_offset = (mac_start - scan_start) % md_size; * * However, division is not a constant-time operation (at least on Intel * chips). Thus we enumerate the possible values of md_size and handle each * separately. The value of |md_size| is public information (it's determined * by the cipher suite in the ServerHello) so our timing can vary based on * its value. */ rotate_offset = mac_start - scan_start; /* rotate_offset can be, at most, 255 (bytes of padding) + 1 (padding length) * + md_size = 256 + 48 (since SHA-384 is the largest hash) = 304. */ assert(rotate_offset <= 304); /* Below is an SMT-LIB2 verification that the Barrett reductions below are * correct within this range: * * (define-fun barrett ( * (x (_ BitVec 32)) * (mul (_ BitVec 32)) * (shift (_ BitVec 32)) * (divisor (_ BitVec 32)) ) (_ BitVec 32) * (let ((q (bvsub x (bvmul divisor (bvlshr (bvmul x mul) shift))) )) * (ite (bvuge q divisor) * (bvsub q divisor) * q))) * * (declare-fun x () (_ BitVec 32)) * * (assert (or * (let ( * (divisor (_ bv20 32)) * (mul (_ bv25 32)) * (shift (_ bv9 32)) * (limit (_ bv853 32))) * * (and (bvule x limit) (not (= (bvurem x divisor) * (barrett x mul shift divisor))))) * * (let ( * (divisor (_ bv48 32)) * (mul (_ bv10 32)) * (shift (_ bv9 32)) * (limit (_ bv768 32))) * * (and (bvule x limit) (not (= (bvurem x divisor) * (barrett x mul shift divisor))))) * )) * * (check-sat) * (get-model) */ if (md_size == 16) { rotate_offset &= 15; } else if (md_size == 20) { /* 1/20 is approximated as 25/512 and then Barrett reduction is used. * Analytically, this is correct for 0 <= rotate_offset <= 853. */ unsigned q = (rotate_offset * 25) >> 9; rotate_offset -= q * 20; rotate_offset -= constant_time_select(constant_time_ge(rotate_offset, 20), 20, 0); } else if (md_size == 32) {