In multiple places our RSA code assumes that the key size is a multiple
of 32 bit.

E.g in rsa_gen_key_prop() and rsa_mod_exp_sw() we allocate uint32_t[]
buffers for the modulus based on this assumption.

Signed-off-by: Heinrich Schuchardt <[email protected]>
---
 lib/rsa/rsa-keyprop.c | 11 +++++++++++
 lib/rsa/rsa-mod-exp.c | 10 ++++++++++
 2 files changed, 21 insertions(+)

diff --git a/lib/rsa/rsa-keyprop.c b/lib/rsa/rsa-keyprop.c
index 8a1ba847dc2..b01f8a6398e 100644
--- a/lib/rsa/rsa-keyprop.c
+++ b/lib/rsa/rsa-keyprop.c
@@ -679,6 +679,17 @@ int rsa_gen_key_prop(const void *key, uint32_t keylen, 
struct key_prop **prop)
        /* removing leading 0's */
        for (i = 0; i < rsa_key.n_sz && !rsa_key.n[i]; i++)
                ;
+       /*
+        * Our code cannot handle key sizes that are not a multiple of 32.
+        * NIST FIPS 186-5, appendix A 1.3 requires the topmost bit to be set.
+        * Reject all other key sizes.
+        */
+       if (i >= rsa_key.n_sz ||
+           (rsa_key.n_sz - i) % sizeof(uint32_t) ||
+           !(rsa_key.n[i] & 0x80)) {
+               ret = -EINVAL;
+               goto out;
+       }
        (*prop)->num_bits = (rsa_key.n_sz - i) * 8;
        (*prop)->modulus = malloc(rsa_key.n_sz - i);
        if (!(*prop)->modulus) {
diff --git a/lib/rsa/rsa-mod-exp.c b/lib/rsa/rsa-mod-exp.c
index 5b3ea02f82f..454f2172d17 100644
--- a/lib/rsa/rsa-mod-exp.c
+++ b/lib/rsa/rsa-mod-exp.c
@@ -283,6 +283,16 @@ int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
                      key.len, RSA_MIN_KEY_BITS, RSA_MAX_KEY_BITS);
                return -EFAULT;
        }
+       /*
+        * Our code cannot handle key sizes that are not a multiple of 32.
+        * NIST FIPS 186-5, appendix A 1.3 requires the topmost bit to be set.
+        * Reject all other key sizes.
+        */
+       if (key.len % (sizeof(uint32_t) * 8)) {
+               debug("RSA key bits %u is not a multiple of %zu\n", key.len,
+                     sizeof(uint32_t) * 8);
+               return -EFAULT;
+       }
        key.len /= sizeof(uint32_t) * 8;
        uint32_t key1[key.len], key2[key.len];
 
-- 
2.53.0

Reply via email to