diff options
author | Jens Wiklander <jens.wiklander@linaro.org> | 2020-08-18 15:15:10 +0200 |
---|---|---|
committer | Jérôme Forissier <jerome@forissier.org> | 2020-09-29 12:48:24 +0200 |
commit | 338b123ee66ca6694372564000226549c99806b1 (patch) | |
tree | 7d6c5d103f1ba11c7758cea1dbf6a83436da1ca3 /core/tee/tee_svc_cryp.c | |
parent | 9760936ca533071c45e14644bb31d73af883a11c (diff) |
core: syscall_obj_generate_key() check public rsa exponent
The v1.1 spec [1] requires that the NIST SP800-56B [2] rules to be
followed when generating an RSA key.
Adds a check when generating a RSA key that the supplied exponent confirms
with the requirements in NIST SP800-56B, thas is, the key must be odd and
in the range 65537 <= e < 2^256.
[1]: GlobalPlatform TEE Internal Core API Specification v1.1
Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
Link [2]: https://csrc.nist.gov/publications/detail/sp/800-56b/rev-2/final
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'core/tee/tee_svc_cryp.c')
-rw-r--r-- | core/tee/tee_svc_cryp.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/core/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index 182be932..44f63deb 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -1691,12 +1691,46 @@ TEE_Result syscall_cryp_obj_copy(unsigned long dst, unsigned long src) return TEE_SUCCESS; } +static TEE_Result check_pub_rsa_key(struct bignum *e) +{ + size_t n = crypto_bignum_num_bytes(e); + uint8_t bin_key[256 / 8] = { 0 }; + + /* + * NIST SP800-56B requires public RSA key to be an odd integer in + * the range 65537 <= e < 2^256. + */ + + if (n > sizeof(bin_key) || n < 3) + return TEE_ERROR_BAD_PARAMETERS; + + crypto_bignum_bn2bin(e, bin_key); + + if (!(bin_key[0] & 1)) /* key must be odd */ + return TEE_ERROR_BAD_PARAMETERS; + + if (n == 3) { + uint32_t key = 0; + + for (n = 0; n < 3; n++) { + key <<= 8; + key |= bin_key[n]; + } + + if (key < 65537) + return TEE_ERROR_BAD_PARAMETERS; + } + + /* key is larger than 65537 */ + return TEE_SUCCESS; +} + static TEE_Result tee_svc_obj_generate_key_rsa( struct tee_obj *o, const struct tee_cryp_obj_type_props *type_props, uint32_t key_size, const TEE_Attribute *params, uint32_t param_count) { - TEE_Result res; + TEE_Result res = TEE_SUCCESS; struct rsa_keypair *key = o->attr; uint32_t e = TEE_U32_TO_BIG_ENDIAN(65537); @@ -1705,8 +1739,13 @@ static TEE_Result tee_svc_obj_generate_key_rsa( param_count); if (res != TEE_SUCCESS) return res; - if (!get_attribute(o, type_props, TEE_ATTR_RSA_PUBLIC_EXPONENT)) + if (get_attribute(o, type_props, TEE_ATTR_RSA_PUBLIC_EXPONENT)) { + res = check_pub_rsa_key(key->e); + if (res) + return res; + } else { crypto_bignum_bin2bn((const uint8_t *)&e, sizeof(e), key->e); + } res = crypto_acipher_gen_rsa_key(key, key_size); if (res != TEE_SUCCESS) return res; |