Fix truncation warnings with the iteration count
They end up in uint64_t frequently right now just because the CBS APIs
use uint64_t, but we don't actually accept that large of an iteration
count.
Also use uint32_t instead of unsigned. This type should be sized based
on how large of an iteration count we think is reasonable, not something
platform-dependent.
Bug: 516
Change-Id: Ie5ff379af6bc65c5e4d25f4d10774bd819f08a50
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/61426
Commit-Queue: David Benjamin <davidben@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
diff --git a/crypto/evp/pbkdf.c b/crypto/evp/pbkdf.c
index f23a74b..33bfe8f 100644
--- a/crypto/evp/pbkdf.c
+++ b/crypto/evp/pbkdf.c
@@ -63,7 +63,7 @@
int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len,
- const uint8_t *salt, size_t salt_len, unsigned iterations,
+ const uint8_t *salt, size_t salt_len, uint32_t iterations,
const EVP_MD *digest, size_t key_len, uint8_t *out_key) {
// See RFC 8018, section 5.2.
int ret = 0;
@@ -98,7 +98,7 @@
}
OPENSSL_memcpy(out_key, digest_tmp, todo);
- for (unsigned j = 1; j < iterations; j++) {
+ for (uint32_t j = 1; j < iterations; j++) {
// Compute the remaining U_* values and XOR.
if (!HMAC_Init_ex(&hctx, NULL, 0, NULL, NULL) ||
!HMAC_Update(&hctx, digest_tmp, md_len) ||
@@ -139,7 +139,7 @@
int PKCS5_PBKDF2_HMAC_SHA1(const char *password, size_t password_len,
const uint8_t *salt, size_t salt_len,
- unsigned iterations, size_t key_len,
+ uint32_t iterations, size_t key_len,
uint8_t *out_key) {
return PKCS5_PBKDF2_HMAC(password, password_len, salt, salt_len, iterations,
EVP_sha1(), key_len, out_key);
diff --git a/crypto/pkcs8/internal.h b/crypto/pkcs8/internal.h
index ab84c82..483e4b6 100644
--- a/crypto/pkcs8/internal.h
+++ b/crypto/pkcs8/internal.h
@@ -87,13 +87,13 @@
// key material to |out| and returns one. Otherwise, it returns zero. |id|
// should be one of the |PKCS12_*_ID| values.
int pkcs12_key_gen(const char *pass, size_t pass_len, const uint8_t *salt,
- size_t salt_len, uint8_t id, unsigned iterations,
+ size_t salt_len, uint8_t id, uint32_t iterations,
size_t out_len, uint8_t *out, const EVP_MD *md);
// pkcs12_pbe_encrypt_init configures |ctx| for encrypting with a PBES1 scheme
// defined in PKCS#12. It writes the corresponding AlgorithmIdentifier to |out|.
int pkcs12_pbe_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, int alg,
- unsigned iterations, const char *pass,
+ uint32_t iterations, const char *pass,
size_t pass_len, const uint8_t *salt,
size_t salt_len);
@@ -121,7 +121,7 @@
// as defined in RFC 2998, with the specified parameters. It writes the
// corresponding AlgorithmIdentifier to |out|.
int PKCS5_pbe2_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx,
- const EVP_CIPHER *cipher, unsigned iterations,
+ const EVP_CIPHER *cipher, uint32_t iterations,
const char *pass, size_t pass_len,
const uint8_t *salt, size_t salt_len);
diff --git a/crypto/pkcs8/p5_pbev2.c b/crypto/pkcs8/p5_pbev2.c
index e58cf44..173fa98 100644
--- a/crypto/pkcs8/p5_pbev2.c
+++ b/crypto/pkcs8/p5_pbev2.c
@@ -144,7 +144,7 @@
}
static int pkcs5_pbe2_cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
- const EVP_MD *pbkdf2_md, unsigned iterations,
+ const EVP_MD *pbkdf2_md, uint32_t iterations,
const char *pass, size_t pass_len,
const uint8_t *salt, size_t salt_len,
const uint8_t *iv, size_t iv_len, int enc) {
@@ -162,7 +162,7 @@
}
int PKCS5_pbe2_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx,
- const EVP_CIPHER *cipher, unsigned iterations,
+ const EVP_CIPHER *cipher, uint32_t iterations,
const char *pass, size_t pass_len,
const uint8_t *salt, size_t salt_len) {
int cipher_nid = EVP_CIPHER_nid(cipher);
@@ -310,7 +310,7 @@
return 0;
}
- return pkcs5_pbe2_cipher_init(ctx, cipher, md, (unsigned)iterations, pass,
+ return pkcs5_pbe2_cipher_init(ctx, cipher, md, (uint32_t)iterations, pass,
pass_len, CBS_data(&salt), CBS_len(&salt),
CBS_data(&iv), CBS_len(&iv), 0 /* decrypt */);
}
diff --git a/crypto/pkcs8/pkcs8.c b/crypto/pkcs8/pkcs8.c
index 6dd111b..4bc337b 100644
--- a/crypto/pkcs8/pkcs8.c
+++ b/crypto/pkcs8/pkcs8.c
@@ -106,7 +106,7 @@
}
int pkcs12_key_gen(const char *pass, size_t pass_len, const uint8_t *salt,
- size_t salt_len, uint8_t id, unsigned iterations,
+ size_t salt_len, uint8_t id, uint32_t iterations,
size_t out_len, uint8_t *out, const EVP_MD *md) {
// See https://tools.ietf.org/html/rfc7292#appendix-B. Quoted parts of the
// specification have errata applied and other typos fixed.
@@ -182,7 +182,7 @@
!EVP_DigestFinal_ex(&ctx, A, &A_len)) {
goto err;
}
- for (unsigned iter = 1; iter < iterations; iter++) {
+ for (uint32_t iter = 1; iter < iterations; iter++) {
if (!EVP_DigestInit_ex(&ctx, md, NULL) ||
!EVP_DigestUpdate(&ctx, A, A_len) ||
!EVP_DigestFinal_ex(&ctx, A, &A_len)) {
@@ -229,7 +229,7 @@
}
static int pkcs12_pbe_cipher_init(const struct pbe_suite *suite,
- EVP_CIPHER_CTX *ctx, unsigned iterations,
+ EVP_CIPHER_CTX *ctx, uint32_t iterations,
const char *pass, size_t pass_len,
const uint8_t *salt, size_t salt_len,
int is_encrypt) {
@@ -271,7 +271,7 @@
return 0;
}
- return pkcs12_pbe_cipher_init(suite, ctx, (unsigned)iterations, pass,
+ return pkcs12_pbe_cipher_init(suite, ctx, (uint32_t)iterations, pass,
pass_len, CBS_data(&salt), CBS_len(&salt),
0 /* decrypt */);
}
@@ -329,7 +329,7 @@
}
int pkcs12_pbe_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, int alg,
- unsigned iterations, const char *pass,
+ uint32_t iterations, const char *pass,
size_t pass_len, const uint8_t *salt,
size_t salt_len) {
const struct pbe_suite *suite = get_pkcs12_pbe_suite(alg);
@@ -489,10 +489,10 @@
// it. See 5693a30813a031d3921a016a870420e7eb93ec90 in OpenSSL.
int alg_ok;
if (pbe_nid == -1) {
- alg_ok = PKCS5_pbe2_encrypt_init(&epki, &ctx, cipher, (unsigned)iterations,
+ alg_ok = PKCS5_pbe2_encrypt_init(&epki, &ctx, cipher, (uint32_t)iterations,
pass, pass_len, salt, salt_len);
} else {
- alg_ok = pkcs12_pbe_encrypt_init(&epki, &ctx, pbe_nid, (unsigned)iterations,
+ alg_ok = pkcs12_pbe_encrypt_init(&epki, &ctx, pbe_nid, (uint32_t)iterations,
pass, pass_len, salt, salt_len);
}
if (!alg_ok) {
diff --git a/crypto/pkcs8/pkcs8_x509.c b/crypto/pkcs8/pkcs8_x509.c
index 83d34e6..87c0961 100644
--- a/crypto/pkcs8/pkcs8_x509.c
+++ b/crypto/pkcs8/pkcs8_x509.c
@@ -87,6 +87,7 @@
static const uint64_t kIterationsLimit = 100 * 1000000;
#endif
+ assert(kIterationsLimit <= UINT32_MAX);
return 0 < iterations && iterations <= kIterationsLimit;
}
@@ -554,7 +555,7 @@
static int pkcs12_check_mac(int *out_mac_ok, const char *password,
size_t password_len, const CBS *salt,
- unsigned iterations, const EVP_MD *md,
+ uint32_t iterations, const EVP_MD *md,
const CBS *authsafes, const CBS *expected_mac) {
int ret = 0;
uint8_t hmac_key[EVP_MAX_MD_SIZE];
@@ -676,13 +677,15 @@
}
// The iteration count is optional and the default is one.
- uint64_t iterations = 1;
+ uint32_t iterations = 1;
if (CBS_len(&mac_data) > 0) {
- if (!CBS_get_asn1_uint64(&mac_data, &iterations) ||
- !pkcs12_iterations_acceptable(iterations)) {
+ uint64_t iterations_u64;
+ if (!CBS_get_asn1_uint64(&mac_data, &iterations_u64) ||
+ !pkcs12_iterations_acceptable(iterations_u64)) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
+ iterations = (uint32_t)iterations_u64;
}
int mac_ok;
@@ -1056,7 +1059,7 @@
}
static int add_encrypted_data(CBB *out, int pbe_nid, const char *password,
- size_t password_len, unsigned iterations,
+ size_t password_len, uint32_t iterations,
const uint8_t *in, size_t in_len) {
uint8_t salt[PKCS5_SALT_LEN];
if (!RAND_bytes(salt, sizeof(salt))) {
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 1cdaca2..6f6eaa9 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -475,7 +475,7 @@
// returns one on success and zero on allocation failure or if iterations is 0.
OPENSSL_EXPORT int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len,
const uint8_t *salt, size_t salt_len,
- unsigned iterations, const EVP_MD *digest,
+ uint32_t iterations, const EVP_MD *digest,
size_t key_len, uint8_t *out_key);
// PKCS5_PBKDF2_HMAC_SHA1 is the same as PKCS5_PBKDF2_HMAC, but with |digest|
@@ -483,7 +483,7 @@
OPENSSL_EXPORT int PKCS5_PBKDF2_HMAC_SHA1(const char *password,
size_t password_len,
const uint8_t *salt, size_t salt_len,
- unsigned iterations, size_t key_len,
+ uint32_t iterations, size_t key_len,
uint8_t *out_key);
// EVP_PBE_scrypt expands |password| into a secret key of length |key_len| using