Skip to content

Commit

Permalink
core: pass TEE_ATTR_RSA_OAEP_MGF_HASH to RSA-OAEP implementations
Browse files Browse the repository at this point in the history
OP-TEE currently doesn't support using a different hash for MGF1
with RSA-OAEP. However, this is required for AOSP compatibility
(e.g. in EncryptionOperationsTest.RsaOaepWithMGFDigestSuccess [1]).

Pass the MGF1 attribute to crypto implementations. Note that
only libtomcrypt supports this feature at the moment, so other
implementations will either fail or fall back to libtomcrypt when
passed a different MGF1 hash.

Link: https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/main/security/keymint/aidl/vts/functional/KeyMintTest.cpp#5552 [1]
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
  • Loading branch information
samitolvanen committed Apr 8, 2024
1 parent ddeceb1 commit 56edae5
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 35 deletions.
2 changes: 2 additions & 0 deletions core/crypto/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo __unused,
struct rsa_keypair *key __unused,
const uint8_t *label __unused,
size_t label_len __unused,
uint32_t mgf_algo __unused,
const uint8_t *src __unused,
size_t src_len __unused,
uint8_t *dst __unused,
Expand All @@ -609,6 +610,7 @@ TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo __unused,
struct rsa_public_key *key __unused,
const uint8_t *label __unused,
size_t label_len __unused,
uint32_t mgf_algo __unused,
const uint8_t *src __unused,
size_t src_len __unused,
uint8_t *dst __unused,
Expand Down
8 changes: 4 additions & 4 deletions core/drivers/crypto/caam/acipher/caam_rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -890,8 +890,8 @@ static TEE_Result do_oaep_decoding(struct drvcrypt_rsa_ed *rsa_data)
*
* Note: Use same buffer for seed and seedMask
*/
mgf_data.hash_algo = rsa_data->hash_algo;
mgf_data.digest_size = rsa_data->digest_size;
mgf_data.hash_algo = rsa_data->mgf_algo;
mgf_data.digest_size = rsa_data->mgf_size;
mgf_data.seed.data = maskedDB.data;
mgf_data.seed.length = maskedDB.length;
mgf_data.mask.data = seed.data;
Expand Down Expand Up @@ -1123,8 +1123,8 @@ static TEE_Result do_oaep_encoding(struct drvcrypt_rsa_ed *rsa_data)
* Generate a Mask of the seed value
* dbMask = MGF(seed, k - hLen - 1)
*/
mgf_data.hash_algo = rsa_data->hash_algo;
mgf_data.digest_size = rsa_data->digest_size;
mgf_data.hash_algo = rsa_data->mgf_algo;
mgf_data.digest_size = rsa_data->mgf_size;
mgf_data.seed.data = seed.data;
mgf_data.seed.length = seed.length;
mgf_data.mask.data = dbMask.data;
Expand Down
14 changes: 14 additions & 0 deletions core/drivers/crypto/crypto_api/acipher/rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ TEE_Result crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key,

TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo, struct rsa_keypair *key,
const uint8_t *label, size_t label_len,
uint32_t mgf_algo,
const uint8_t *cipher,
size_t cipher_len, uint8_t *msg,
size_t *msg_len)
Expand Down Expand Up @@ -231,6 +232,12 @@ TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo, struct rsa_keypair *key,
if (ret != TEE_SUCCESS)
return ret;

rsa_data.mgf_algo = mgf_algo;
ret = tee_alg_get_digest_size(rsa_data.mgf_algo,
&rsa_data.mgf_size);
if (ret != TEE_SUCCESS)
return ret;

rsa_data.mgf = &drvcrypt_rsa_mgf1;
}

Expand Down Expand Up @@ -261,6 +268,7 @@ TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo, struct rsa_keypair *key,
TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo,
struct rsa_public_key *key,
const uint8_t *label, size_t label_len,
uint32_t mgf_algo,
const uint8_t *msg, size_t msg_len,
uint8_t *cipher, size_t *cipher_len)
{
Expand Down Expand Up @@ -322,6 +330,12 @@ TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo,
rsa_data.key.n_size - 2 * rsa_data.digest_size - 2)
return TEE_ERROR_BAD_PARAMETERS;

rsa_data.mgf_algo = mgf_algo;
ret = tee_alg_get_digest_size(rsa_data.mgf_algo,
&rsa_data.mgf_size);
if (ret != TEE_SUCCESS)
return ret;

rsa_data.mgf = &drvcrypt_rsa_mgf1;
}

Expand Down
2 changes: 2 additions & 0 deletions core/drivers/crypto/crypto_api/include/drvcrypt_acipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ struct drvcrypt_rsa_ed {
struct drvcrypt_buf message; /* Message to encrypt or decrypted */
struct drvcrypt_buf cipher; /* Cipher encrypted or to decrypt */
struct drvcrypt_buf label; /* Additional Label (RSAES) */
uint32_t mgf_algo; /* MGF1 hash algorithm (RSAES) */
size_t mgf_size; /* MGF1 hash digest size (RSAES) */

/* RSA Mask Generation function */
TEE_Result (*mgf)(struct drvcrypt_rsa_mgf *mgf_data);
Expand Down
8 changes: 6 additions & 2 deletions core/drivers/crypto/se050/core/rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,7 @@ static TEE_Result encrypt_fallback(struct drvcrypt_rsa_ed *p)
p->key.key,
p->label.data,
p->label.length,
p->mgf_algo,
p->message.data,
p->message.length,
p->cipher.data,
Expand Down Expand Up @@ -720,7 +721,8 @@ static TEE_Result do_encrypt(struct drvcrypt_rsa_ed *rsa_data)
&rsa_data->cipher.length);

case DRVCRYPT_RSA_OAEP:
if (rsa_data->hash_algo != TEE_ALG_SHA1)
if (rsa_data->hash_algo != TEE_ALG_SHA1 ||
rsa_data->hash_algo != rsa_data->mgf_algo)
return encrypt_fallback(rsa_data);

return encrypt_es(TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1,
Expand Down Expand Up @@ -764,6 +766,7 @@ static TEE_Result decrypt_fallback(struct drvcrypt_rsa_ed *p)
p->key.key,
p->label.data,
p->label.length,
p->mgf_algo,
p->cipher.data,
p->cipher.length,
p->message.data,
Expand Down Expand Up @@ -798,7 +801,8 @@ static TEE_Result do_decrypt(struct drvcrypt_rsa_ed *rsa_data)
&rsa_data->message.length);

case DRVCRYPT_RSA_OAEP:
if (rsa_data->hash_algo != TEE_ALG_SHA1)
if (rsa_data->hash_algo != TEE_ALG_SHA1 ||
rsa_data->hash_algo != rsa_data->mgf_algo)
return decrypt_fallback(rsa_data);

return decrypt_es(TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1,
Expand Down
4 changes: 4 additions & 0 deletions core/drivers/crypto/versal/rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ static TEE_Result do_encrypt(struct drvcrypt_rsa_ed *rsa_data)
rsa_data->key.key,
rsa_data->label.data,
rsa_data->label.length,
rsa_data->mgf_algo,
rsa_data->message.data,
rsa_data->message.length,
rsa_data->cipher.data,
Expand All @@ -53,6 +54,7 @@ static TEE_Result do_encrypt(struct drvcrypt_rsa_ed *rsa_data)
rsa_data->key.key,
rsa_data->label.data,
rsa_data->label.length,
rsa_data->mgf_algo,
rsa_data->message.data,
rsa_data->message.length,
rsa_data->cipher.data,
Expand Down Expand Up @@ -133,6 +135,7 @@ static TEE_Result do_decrypt(struct drvcrypt_rsa_ed *rsa_data)
rsa_data->key.key,
rsa_data->label.data,
rsa_data->label.length,
rsa_data->mgf_algo,
rsa_data->cipher.data,
rsa_data->cipher.length,
rsa_data->message.data,
Expand All @@ -142,6 +145,7 @@ static TEE_Result do_decrypt(struct drvcrypt_rsa_ed *rsa_data)
rsa_data->key.key,
rsa_data->label.data,
rsa_data->label.length,
rsa_data->mgf_algo,
rsa_data->cipher.data,
rsa_data->cipher.length,
rsa_data->message.data,
Expand Down
2 changes: 2 additions & 0 deletions core/include/crypto/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,13 @@ TEE_Result crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key,
uint8_t *dst, size_t *dst_len);
TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo, struct rsa_keypair *key,
const uint8_t *label, size_t label_len,
uint32_t mgf_algo,
const uint8_t *src, size_t src_len,
uint8_t *dst, size_t *dst_len);
TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo,
struct rsa_public_key *key,
const uint8_t *label, size_t label_len,
uint32_t mgf_algo,
const uint8_t *src, size_t src_len,
uint8_t *dst, size_t *dst_len);
/* RSA SSA sign/verify: if salt_len == -1, use default value */
Expand Down
8 changes: 6 additions & 2 deletions core/include/crypto/crypto_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -532,14 +532,18 @@ TEE_Result sw_crypto_acipher_rsanopad_encrypt(struct rsa_public_key *key,
TEE_Result sw_crypto_acipher_rsaes_decrypt(uint32_t algo,
struct rsa_keypair *key,
const uint8_t *label,
size_t label_len, const uint8_t *src,
size_t label_len,
uint32_t mgf_algo,
const uint8_t *src,
size_t src_len, uint8_t *dst,
size_t *dst_len);

TEE_Result sw_crypto_acipher_rsaes_encrypt(uint32_t algo,
struct rsa_public_key *key,
const uint8_t *label,
size_t label_len, const uint8_t *src,
size_t label_len,
uint32_t mgf_algo,
const uint8_t *src,
size_t src_len, uint8_t *dst,
size_t *dst_len);

Expand Down
50 changes: 41 additions & 9 deletions core/lib/libtomcrypt/rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,41 +30,47 @@ static TEE_Result tee_algo_to_ltc_hashindex(uint32_t algo, int *ltc_hashindex)
{
switch (algo) {
#if defined(_CFG_CORE_LTC_SHA1_DESC)
case TEE_ALG_SHA1:
case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
*ltc_hashindex = find_hash("sha1");
break;
#endif
#if defined(_CFG_CORE_LTC_MD5_DESC)
case TEE_ALG_MD5:
case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5:
case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_MD5:
*ltc_hashindex = find_hash("md5");
break;
#endif
#if defined(_CFG_CORE_LTC_SHA224_DESC)
case TEE_ALG_SHA224:
case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
*ltc_hashindex = find_hash("sha224");
break;
#endif
#if defined(_CFG_CORE_LTC_SHA256_DESC)
case TEE_ALG_SHA256:
case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
*ltc_hashindex = find_hash("sha256");
break;
#endif
#if defined(_CFG_CORE_LTC_SHA384_DESC)
case TEE_ALG_SHA384:
case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
*ltc_hashindex = find_hash("sha384");
break;
#endif
#if defined(_CFG_CORE_LTC_SHA512_DESC)
case TEE_ALG_SHA512:
case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
Expand Down Expand Up @@ -319,22 +325,26 @@ TEE_Result sw_crypto_acipher_rsanopad_decrypt(struct rsa_keypair *key,
TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo,
struct rsa_keypair *key,
const uint8_t *label,
size_t label_len, const uint8_t *src,
size_t label_len,
uint32_t mgf_algo,
const uint8_t *src,
size_t src_len, uint8_t *dst,
size_t *dst_len)
__weak __alias("sw_crypto_acipher_rsaes_decrypt");

TEE_Result sw_crypto_acipher_rsaes_decrypt(uint32_t algo,
struct rsa_keypair *key,
const uint8_t *label,
size_t label_len, const uint8_t *src,
size_t label_len,
uint32_t mgf_algo,
const uint8_t *src,
size_t src_len, uint8_t *dst,
size_t *dst_len)
{
TEE_Result res = TEE_SUCCESS;
void *buf = NULL;
unsigned long blen;
int ltc_hashindex, ltc_res, ltc_stat, ltc_rsa_algo;
int ltc_hashindex, ltc_mgfindex, ltc_res, ltc_stat, ltc_rsa_algo;
size_t mod_size;
rsa_key ltc_key = { 0, };

Expand All @@ -356,6 +366,15 @@ TEE_Result sw_crypto_acipher_rsaes_decrypt(uint32_t algo,
EMSG("tee_algo_to_ltc_hashindex() returned %d", (int)res);
goto out;
}
if (algo != TEE_ALG_RSAES_PKCS1_V1_5) {
res = tee_algo_to_ltc_hashindex(mgf_algo, &ltc_mgfindex);
if (res != TEE_SUCCESS) {
EMSG("tee_algo_to_ltc_hashindex() returned %d for mgf algo %x", (int)res, mgf_algo);
goto out;
}
} else {
ltc_mgfindex = -1;
}

/*
* Use a temporary buffer since we don't know exactly how large
Expand All @@ -380,8 +399,8 @@ TEE_Result sw_crypto_acipher_rsaes_decrypt(uint32_t algo,

ltc_res = rsa_decrypt_key_ex(src, src_len, buf, &blen,
((label_len == 0) ? 0 : label), label_len,
ltc_hashindex, -1, ltc_rsa_algo, &ltc_stat,
&ltc_key);
ltc_mgfindex, ltc_hashindex, ltc_rsa_algo,
&ltc_stat, &ltc_key);
switch (ltc_res) {
case CRYPT_PK_INVALID_PADDING:
case CRYPT_INVALID_PACKET:
Expand Down Expand Up @@ -424,21 +443,25 @@ TEE_Result sw_crypto_acipher_rsaes_decrypt(uint32_t algo,
TEE_Result crypto_acipher_rsaes_encrypt(uint32_t algo,
struct rsa_public_key *key,
const uint8_t *label,
size_t label_len, const uint8_t *src,
size_t label_len,
uint32_t mgf_algo,
const uint8_t *src,
size_t src_len, uint8_t *dst,
size_t *dst_len)
__weak __alias("sw_crypto_acipher_rsaes_encrypt");

TEE_Result sw_crypto_acipher_rsaes_encrypt(uint32_t algo,
struct rsa_public_key *key,
const uint8_t *label,
size_t label_len, const uint8_t *src,
size_t label_len,
uint32_t mgf_algo,
const uint8_t *src,
size_t src_len, uint8_t *dst,
size_t *dst_len)
{
TEE_Result res;
uint32_t mod_size;
int ltc_hashindex, ltc_res, ltc_rsa_algo;
int ltc_hashindex, ltc_mgfindex, ltc_res, ltc_rsa_algo;
rsa_key ltc_key = {
.type = PK_PUBLIC,
.e = key->e,
Expand All @@ -458,6 +481,14 @@ TEE_Result sw_crypto_acipher_rsaes_encrypt(uint32_t algo,
if (res != TEE_SUCCESS)
goto out;

if (algo != TEE_ALG_RSAES_PKCS1_V1_5) {
res = tee_algo_to_ltc_hashindex(mgf_algo, &ltc_mgfindex);
if (res != TEE_SUCCESS)
goto out;
} else {
ltc_mgfindex = -1;
}

if (algo == TEE_ALG_RSAES_PKCS1_V1_5)
ltc_rsa_algo = LTC_PKCS_1_V1_5;
else
Expand All @@ -466,7 +497,8 @@ TEE_Result sw_crypto_acipher_rsaes_encrypt(uint32_t algo,
ltc_res = rsa_encrypt_key_ex(src, src_len, dst,
(unsigned long *)(dst_len), label,
label_len, NULL, find_prng("prng_crypto"),
ltc_hashindex, -1, ltc_rsa_algo, &ltc_key);
ltc_mgfindex, ltc_hashindex, ltc_rsa_algo,
&ltc_key);
switch (ltc_res) {
case CRYPT_PK_INVALID_PADDING:
case CRYPT_INVALID_PACKET:
Expand Down

0 comments on commit 56edae5

Please sign in to comment.