aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2019-03-11 11:28:05 +0100
committerJérôme Forissier <jerome.forissier@linaro.org>2019-03-28 14:11:23 +0100
commit1ac17bb54d041c5a638904d737d960695b823afc (patch)
tree894d74f4b8d9a01de6c297ca708d3e5b0fb6c2e4 /core
parentda1de5576fa9f0f89110485a749c1dcab6499f74 (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.h30
-rw-r--r--core/lib/libtomcrypt/dsa.c205
-rw-r--r--core/lib/libtomcrypt/src/tee_ltc_provider.c195
-rw-r--r--core/lib/libtomcrypt/sub.mk1
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, &ltc_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(&ltc_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(&ltc_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"), &ltc_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, &ltc_stat, &ltc_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, &ltc_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(&ltc_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(&ltc_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"), &ltc_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, &ltc_stat, &ltc_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