summaryrefslogtreecommitdiff
path: root/core/tee/tee_svc_cryp.c
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2020-08-18 15:15:10 +0200
committerJérôme Forissier <jerome@forissier.org>2020-09-29 12:48:24 +0200
commit338b123ee66ca6694372564000226549c99806b1 (patch)
tree7d6c5d103f1ba11c7758cea1dbf6a83436da1ca3 /core/tee/tee_svc_cryp.c
parent9760936ca533071c45e14644bb31d73af883a11c (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.c43
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;