diff options
author | Jens Wiklander <jens.wiklander@linaro.org> | 2019-03-11 11:28:05 +0100 |
---|---|---|
committer | Jérôme Forissier <jerome.forissier@linaro.org> | 2019-03-28 14:11:23 +0100 |
commit | 1ac17bb54d041c5a638904d737d960695b823afc (patch) | |
tree | 894d74f4b8d9a01de6c297ca708d3e5b0fb6c2e4 /core | |
parent | da1de5576fa9f0f89110485a749c1dcab6499f74 (diff) |
core: ltc: move dsa wrappers to separate file
Moves the DSA wrappers in tee_ltc_provider.c to its own file, dsa.c.
Acked-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'core')
-rw-r--r-- | core/lib/libtomcrypt/acipher_helpers.h | 30 | ||||
-rw-r--r-- | core/lib/libtomcrypt/dsa.c | 205 | ||||
-rw-r--r-- | core/lib/libtomcrypt/src/tee_ltc_provider.c | 195 | ||||
-rw-r--r-- | core/lib/libtomcrypt/sub.mk | 1 |
4 files changed, 236 insertions, 195 deletions
diff --git a/core/lib/libtomcrypt/acipher_helpers.h b/core/lib/libtomcrypt/acipher_helpers.h new file mode 100644 index 00000000..e439d35c --- /dev/null +++ b/core/lib/libtomcrypt/acipher_helpers.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (c) 2014-2019, Linaro Limited + */ + +#include <crypto/crypto.h> +#include <tee_api_defines.h> +#include <types_ext.h> + +static inline bool bn_alloc_max(struct bignum **s) +{ + *s = crypto_bignum_allocate(CFG_CORE_BIGNUM_MAX_BITS); + + return *s; +} + +static inline TEE_Result convert_ltc_verify_status(int ltc_res, int ltc_stat) +{ + switch (ltc_res) { + case CRYPT_OK: + if (ltc_stat == 1) + return TEE_SUCCESS; + else + return TEE_ERROR_SIGNATURE_INVALID; + case CRYPT_INVALID_PACKET: + return TEE_ERROR_SIGNATURE_INVALID; + default: + return TEE_ERROR_GENERIC; + } +} diff --git a/core/lib/libtomcrypt/dsa.c b/core/lib/libtomcrypt/dsa.c new file mode 100644 index 00000000..3fa6301c --- /dev/null +++ b/core/lib/libtomcrypt/dsa.c @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright (c) 2014-2019, Linaro Limited + */ + +#include <crypto/crypto.h> +#include <stdlib.h> +#include <string.h> +#include <tee_api_types.h> +#include <tee/tee_cryp_utl.h> +#include <tomcrypt.h> +#include <trace.h> +#include <utee_defines.h> + +#include "acipher_helpers.h" + +TEE_Result crypto_acipher_alloc_dsa_keypair(struct dsa_keypair *s, + size_t key_size_bits __unused) +{ + memset(s, 0, sizeof(*s)); + if (!bn_alloc_max(&s->g)) + return TEE_ERROR_OUT_OF_MEMORY; + + if (!bn_alloc_max(&s->p)) + goto err; + if (!bn_alloc_max(&s->q)) + goto err; + if (!bn_alloc_max(&s->y)) + goto err; + if (!bn_alloc_max(&s->x)) + goto err; + return TEE_SUCCESS; +err: + crypto_bignum_free(s->g); + crypto_bignum_free(s->p); + crypto_bignum_free(s->q); + crypto_bignum_free(s->y); + return TEE_ERROR_OUT_OF_MEMORY; +} + +TEE_Result crypto_acipher_alloc_dsa_public_key(struct dsa_public_key *s, + size_t key_size_bits __unused) +{ + memset(s, 0, sizeof(*s)); + if (!bn_alloc_max(&s->g)) + return TEE_ERROR_OUT_OF_MEMORY; + + if (!bn_alloc_max(&s->p)) + goto err; + if (!bn_alloc_max(&s->q)) + goto err; + if (!bn_alloc_max(&s->y)) + goto err; + return TEE_SUCCESS; +err: + crypto_bignum_free(s->g); + crypto_bignum_free(s->p); + crypto_bignum_free(s->q); + return TEE_ERROR_OUT_OF_MEMORY; +} + +TEE_Result crypto_acipher_gen_dsa_key(struct dsa_keypair *key, size_t key_size) +{ + TEE_Result res; + dsa_key ltc_tmp_key; + size_t group_size, modulus_size = key_size/8; + int ltc_res; + + if (modulus_size <= 128) + group_size = 20; + else if (modulus_size <= 256) + group_size = 30; + else if (modulus_size <= 384) + group_size = 35; + else + group_size = 40; + + /* Generate the DSA key */ + ltc_res = dsa_make_key(NULL, find_prng("prng_mpa"), group_size, + modulus_size, <c_tmp_key); + if (ltc_res != CRYPT_OK) { + res = TEE_ERROR_BAD_PARAMETERS; + } else if ((size_t)mp_count_bits(ltc_tmp_key.p) != key_size) { + dsa_free(<c_tmp_key); + res = TEE_ERROR_BAD_PARAMETERS; + } else { + /* Copy the key */ + ltc_mp.copy(ltc_tmp_key.g, key->g); + ltc_mp.copy(ltc_tmp_key.p, key->p); + ltc_mp.copy(ltc_tmp_key.q, key->q); + ltc_mp.copy(ltc_tmp_key.y, key->y); + ltc_mp.copy(ltc_tmp_key.x, key->x); + + /* Free the tempory key */ + dsa_free(<c_tmp_key); + res = TEE_SUCCESS; + } + return res; +} + +TEE_Result crypto_acipher_dsa_sign(uint32_t algo, struct dsa_keypair *key, + const uint8_t *msg, size_t msg_len, + uint8_t *sig, size_t *sig_len) +{ + TEE_Result res; + size_t hash_size; + int ltc_res; + void *r, *s; + dsa_key ltc_key = { + .type = PK_PRIVATE, + .qord = mp_unsigned_bin_size(key->g), + .g = key->g, + .p = key->p, + .q = key->q, + .y = key->y, + .x = key->x, + }; + + if (algo != TEE_ALG_DSA_SHA1 && + algo != TEE_ALG_DSA_SHA224 && + algo != TEE_ALG_DSA_SHA256) { + res = TEE_ERROR_NOT_IMPLEMENTED; + goto err; + } + + res = tee_hash_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo), + &hash_size); + if (res != TEE_SUCCESS) + goto err; + if (mp_unsigned_bin_size(ltc_key.q) < hash_size) + hash_size = mp_unsigned_bin_size(ltc_key.q); + if (msg_len != hash_size) { + res = TEE_ERROR_SECURITY; + goto err; + } + + if (*sig_len < 2 * mp_unsigned_bin_size(ltc_key.q)) { + *sig_len = 2 * mp_unsigned_bin_size(ltc_key.q); + res = TEE_ERROR_SHORT_BUFFER; + goto err; + } + + ltc_res = mp_init_multi(&r, &s, NULL); + if (ltc_res != CRYPT_OK) { + res = TEE_ERROR_OUT_OF_MEMORY; + goto err; + } + + ltc_res = dsa_sign_hash_raw(msg, msg_len, r, s, NULL, + find_prng("prng_mpa"), <c_key); + + if (ltc_res == CRYPT_OK) { + *sig_len = 2 * mp_unsigned_bin_size(ltc_key.q); + memset(sig, 0, *sig_len); + mp_to_unsigned_bin(r, (uint8_t *)sig + *sig_len/2 - + mp_unsigned_bin_size(r)); + mp_to_unsigned_bin(s, (uint8_t *)sig + *sig_len - + mp_unsigned_bin_size(s)); + res = TEE_SUCCESS; + } else { + res = TEE_ERROR_GENERIC; + } + + mp_clear_multi(r, s, NULL); + +err: + return res; +} + +TEE_Result crypto_acipher_dsa_verify(uint32_t algo, struct dsa_public_key *key, + const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len) +{ + TEE_Result res; + int ltc_stat, ltc_res; + void *r, *s; + dsa_key ltc_key = { + .type = PK_PUBLIC, + .qord = mp_unsigned_bin_size(key->g), + .g = key->g, + .p = key->p, + .q = key->q, + .y = key->y + }; + + if (algo != TEE_ALG_DSA_SHA1 && + algo != TEE_ALG_DSA_SHA224 && + algo != TEE_ALG_DSA_SHA256) { + res = TEE_ERROR_NOT_IMPLEMENTED; + goto err; + } + + ltc_res = mp_init_multi(&r, &s, NULL); + if (ltc_res != CRYPT_OK) { + res = TEE_ERROR_OUT_OF_MEMORY; + goto err; + } + mp_read_unsigned_bin(r, (uint8_t *)sig, sig_len/2); + mp_read_unsigned_bin(s, (uint8_t *)sig + sig_len/2, sig_len/2); + ltc_res = dsa_verify_hash_raw(r, s, msg, msg_len, <c_stat, <c_key); + mp_clear_multi(r, s, NULL); + res = convert_ltc_verify_status(ltc_res, ltc_stat); +err: + return res; +} diff --git a/core/lib/libtomcrypt/src/tee_ltc_provider.c b/core/lib/libtomcrypt/src/tee_ltc_provider.c index 75373fac..4f247bf3 100644 --- a/core/lib/libtomcrypt/src/tee_ltc_provider.c +++ b/core/lib/libtomcrypt/src/tee_ltc_provider.c @@ -739,201 +739,6 @@ err: #endif /* CFG_CRYPTO_RSA */ -#if defined(CFG_CRYPTO_DSA) - -TEE_Result crypto_acipher_alloc_dsa_keypair(struct dsa_keypair *s, - size_t key_size_bits __unused) -{ - memset(s, 0, sizeof(*s)); - if (!bn_alloc_max(&s->g)) { - return TEE_ERROR_OUT_OF_MEMORY; - } - - if (!bn_alloc_max(&s->p)) - goto err; - if (!bn_alloc_max(&s->q)) - goto err; - if (!bn_alloc_max(&s->y)) - goto err; - if (!bn_alloc_max(&s->x)) - goto err; - return TEE_SUCCESS; -err: - crypto_bignum_free(s->g); - crypto_bignum_free(s->p); - crypto_bignum_free(s->q); - crypto_bignum_free(s->y); - return TEE_ERROR_OUT_OF_MEMORY; -} - -TEE_Result crypto_acipher_alloc_dsa_public_key(struct dsa_public_key *s, - size_t key_size_bits __unused) -{ - memset(s, 0, sizeof(*s)); - if (!bn_alloc_max(&s->g)) { - return TEE_ERROR_OUT_OF_MEMORY; - } - - if (!bn_alloc_max(&s->p)) - goto err; - if (!bn_alloc_max(&s->q)) - goto err; - if (!bn_alloc_max(&s->y)) - goto err; - return TEE_SUCCESS; -err: - crypto_bignum_free(s->g); - crypto_bignum_free(s->p); - crypto_bignum_free(s->q); - return TEE_ERROR_OUT_OF_MEMORY; -} - -TEE_Result crypto_acipher_gen_dsa_key(struct dsa_keypair *key, size_t key_size) -{ - TEE_Result res; - dsa_key ltc_tmp_key; - size_t group_size, modulus_size = key_size/8; - int ltc_res; - - if (modulus_size <= 128) - group_size = 20; - else if (modulus_size <= 256) - group_size = 30; - else if (modulus_size <= 384) - group_size = 35; - else - group_size = 40; - - /* Generate the DSA key */ - ltc_res = dsa_make_key(NULL, find_prng("prng_mpa"), group_size, - modulus_size, <c_tmp_key); - if (ltc_res != CRYPT_OK) { - res = TEE_ERROR_BAD_PARAMETERS; - } else if ((size_t)mp_count_bits(ltc_tmp_key.p) != key_size) { - dsa_free(<c_tmp_key); - res = TEE_ERROR_BAD_PARAMETERS; - } else { - /* Copy the key */ - ltc_mp.copy(ltc_tmp_key.g, key->g); - ltc_mp.copy(ltc_tmp_key.p, key->p); - ltc_mp.copy(ltc_tmp_key.q, key->q); - ltc_mp.copy(ltc_tmp_key.y, key->y); - ltc_mp.copy(ltc_tmp_key.x, key->x); - - /* Free the tempory key */ - dsa_free(<c_tmp_key); - res = TEE_SUCCESS; - } - return res; -} - -TEE_Result crypto_acipher_dsa_sign(uint32_t algo, struct dsa_keypair *key, - const uint8_t *msg, size_t msg_len, - uint8_t *sig, size_t *sig_len) -{ - TEE_Result res; - size_t hash_size; - int ltc_res; - void *r, *s; - dsa_key ltc_key = { - .type = PK_PRIVATE, - .qord = mp_unsigned_bin_size(key->g), - .g = key->g, - .p = key->p, - .q = key->q, - .y = key->y, - .x = key->x, - }; - - if (algo != TEE_ALG_DSA_SHA1 && - algo != TEE_ALG_DSA_SHA224 && - algo != TEE_ALG_DSA_SHA256) { - res = TEE_ERROR_NOT_IMPLEMENTED; - goto err; - } - - res = tee_hash_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo), - &hash_size); - if (res != TEE_SUCCESS) - goto err; - if (mp_unsigned_bin_size(ltc_key.q) < hash_size) - hash_size = mp_unsigned_bin_size(ltc_key.q); - if (msg_len != hash_size) { - res = TEE_ERROR_SECURITY; - goto err; - } - - if (*sig_len < 2 * mp_unsigned_bin_size(ltc_key.q)) { - *sig_len = 2 * mp_unsigned_bin_size(ltc_key.q); - res = TEE_ERROR_SHORT_BUFFER; - goto err; - } - - ltc_res = mp_init_multi(&r, &s, NULL); - if (ltc_res != CRYPT_OK) { - res = TEE_ERROR_OUT_OF_MEMORY; - goto err; - } - - ltc_res = dsa_sign_hash_raw(msg, msg_len, r, s, NULL, - find_prng("prng_mpa"), <c_key); - - if (ltc_res == CRYPT_OK) { - *sig_len = 2 * mp_unsigned_bin_size(ltc_key.q); - memset(sig, 0, *sig_len); - mp_to_unsigned_bin(r, (uint8_t *)sig + *sig_len/2 - - mp_unsigned_bin_size(r)); - mp_to_unsigned_bin(s, (uint8_t *)sig + *sig_len - - mp_unsigned_bin_size(s)); - res = TEE_SUCCESS; - } else { - res = TEE_ERROR_GENERIC; - } - - mp_clear_multi(r, s, NULL); - -err: - return res; -} - -TEE_Result crypto_acipher_dsa_verify(uint32_t algo, struct dsa_public_key *key, - const uint8_t *msg, size_t msg_len, - const uint8_t *sig, size_t sig_len) -{ - TEE_Result res; - int ltc_stat, ltc_res; - void *r, *s; - dsa_key ltc_key = { - .type = PK_PUBLIC, - .qord = mp_unsigned_bin_size(key->g), - .g = key->g, - .p = key->p, - .q = key->q, - .y = key->y - }; - - if (algo != TEE_ALG_DSA_SHA1 && - algo != TEE_ALG_DSA_SHA224 && - algo != TEE_ALG_DSA_SHA256) { - res = TEE_ERROR_NOT_IMPLEMENTED; - goto err; - } - - ltc_res = mp_init_multi(&r, &s, NULL); - if (ltc_res != CRYPT_OK) { - res = TEE_ERROR_OUT_OF_MEMORY; - goto err; - } - mp_read_unsigned_bin(r, (uint8_t *)sig, sig_len/2); - mp_read_unsigned_bin(s, (uint8_t *)sig + sig_len/2, sig_len/2); - ltc_res = dsa_verify_hash_raw(r, s, msg, msg_len, <c_stat, <c_key); - mp_clear_multi(r, s, NULL); - res = convert_ltc_verify_status(ltc_res, ltc_stat); -err: - return res; -} - -#endif /* CFG_CRYPTO_DSA */ #if defined(CFG_CRYPTO_DH) diff --git a/core/lib/libtomcrypt/sub.mk b/core/lib/libtomcrypt/sub.mk index ce9aff2f..1dfe9396 100644 --- a/core/lib/libtomcrypt/sub.mk +++ b/core/lib/libtomcrypt/sub.mk @@ -15,3 +15,4 @@ srcs-$(CFG_CRYPTO_CTR) += ctr.c srcs-$(CFG_CRYPTO_XTS) += xts.c srcs-$(CFG_CRYPTO_CCM) += ccm.c srcs-$(CFG_CRYPTO_AES_GCM_FROM_CRYPTOLIB) += gcm.c +srcs-$(CFG_CRYPTO_DSA) += dsa.c |