Skip to content

Commit 2c375b3

Browse files
karel-msjaeckel
authored andcommitted
RSA OAEP - reject ciphertext values 0 and 1
1 parent 71f45fe commit 2c375b3

2 files changed

Lines changed: 61 additions & 0 deletions

File tree

src/pk/rsa/rsa_decrypt_key.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ int rsa_decrypt_key_v2(const unsigned char *in, unsigned long inlen
2525
int *stat, const rsa_key *key)
2626
{
2727
int err;
28+
unsigned char zero, one;
2829
unsigned char *tmp;
2930
unsigned long modulus_bitlen, modulus_bytelen, x;
3031
ltc_rsa_op_checked op_checked = ltc_rsa_op_checked_init(key, params);
@@ -51,6 +52,20 @@ int rsa_decrypt_key_v2(const unsigned char *in, unsigned long inlen
5152
return CRYPT_INVALID_PACKET;
5253
}
5354

55+
/* SP 800-56B Rev. 2 Section 7.1.2.1 says to reject ciphertext values 0 and 1 */
56+
if (params->padding == LTC_PKCS_1_OAEP) {
57+
zero = one = 0;
58+
for (x = 0; x < inlen; ++x) {
59+
zero |= in[x];
60+
if (x == inlen - 1) {
61+
one |= (unsigned char)(in[x] ^ 0x01);
62+
} else {
63+
one |= in[x];
64+
}
65+
}
66+
if (zero == 0 || one == 0) return CRYPT_INVALID_PACKET;
67+
}
68+
5469
/* allocate ram */
5570
tmp = XMALLOC(inlen);
5671
if (tmp == NULL) {

tests/rsa_test.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,51 @@ static int s_rsa_pss_test(void)
521521
return CRYPT_OK;
522522
}
523523

524+
static int s_rsa_oaep_small_ciphertext_test(int prng_idx)
525+
{
526+
rsa_key key;
527+
unsigned char ciphertext[256], plaintext[256], ct_zero[256], ct_one[256];
528+
unsigned long ciphertext_len, plaintext_len, modulus_len;
529+
int hash_idx, stat;
530+
const unsigned char msg[] = "hello strict-mode roundtrip";
531+
ltc_rsa_op_parameters rsa_params = {
532+
.padding = LTC_PKCS_1_OAEP,
533+
};
534+
535+
hash_idx = find_hash("sha256");
536+
if (hash_idx == -1) return CRYPT_NOP;
537+
538+
rsa_params.prng = &yarrow_prng;
539+
rsa_params.wprng = prng_idx;
540+
rsa_params.params.hash_idx = hash_idx;
541+
rsa_params.params.mgf1_hash_idx = hash_idx;
542+
543+
DO(rsa_make_key(&yarrow_prng, prng_idx, 1024/8, 65537, &key));
544+
modulus_len = (unsigned long)rsa_get_size(&key);
545+
ENSURE(modulus_len <= sizeof(ciphertext));
546+
547+
zeromem(ct_zero, modulus_len);
548+
zeromem(ct_one, modulus_len);
549+
ct_one[modulus_len - 1] = 1;
550+
551+
plaintext_len = sizeof(plaintext);
552+
SHOULD_FAIL_WITH(rsa_decrypt_key_v2(ct_zero, modulus_len, plaintext, &plaintext_len, &rsa_params, &stat, &key), CRYPT_INVALID_PACKET);
553+
554+
plaintext_len = sizeof(plaintext);
555+
SHOULD_FAIL_WITH(rsa_decrypt_key_v2(ct_one, modulus_len, plaintext, &plaintext_len, &rsa_params, &stat, &key), CRYPT_INVALID_PACKET);
556+
557+
ciphertext_len = sizeof(ciphertext);
558+
DO(rsa_encrypt_key_v2(msg, sizeof(msg) - 1, ciphertext, &ciphertext_len, &rsa_params, &key));
559+
560+
plaintext_len = sizeof(plaintext);
561+
DO(rsa_decrypt_key_v2(ciphertext, ciphertext_len, plaintext, &plaintext_len, &rsa_params, &stat, &key));
562+
ENSURE(stat == 1);
563+
COMPARE_TESTVECTOR(plaintext, plaintext_len, msg, sizeof(msg) - 1, "rsa oaep roundtrip", 0);
564+
565+
rsa_free(&key);
566+
return CRYPT_OK;
567+
}
568+
524569
int rsa_test(void)
525570
{
526571
unsigned char in[1024], out[1024], tmp[3072];
@@ -564,6 +609,7 @@ int rsa_test(void)
564609
DO(s_rsa_cryptx_issue_69());
565610
DO(s_rsa_issue_301(prng_idx));
566611
DO(s_rsa_public_ubin_e(prng_idx));
612+
DO(s_rsa_oaep_small_ciphertext_test(prng_idx));
567613

568614
/* make 10 random key */
569615
for (cnt = 0; cnt < 10; cnt++) {

0 commit comments

Comments
 (0)