11ac17bb5SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
21ac17bb5SJens Wiklander /*
31ac17bb5SJens Wiklander * Copyright (c) 2014-2019, Linaro Limited
41ac17bb5SJens Wiklander */
51ac17bb5SJens Wiklander
61ac17bb5SJens Wiklander #include <crypto/crypto.h>
71ac17bb5SJens Wiklander #include <stdlib.h>
81ac17bb5SJens Wiklander #include <string.h>
91ac17bb5SJens Wiklander #include <tee_api_types.h>
101ac17bb5SJens Wiklander #include <tee/tee_cryp_utl.h>
111ac17bb5SJens Wiklander #include <trace.h>
121ac17bb5SJens Wiklander #include <utee_defines.h>
131ac17bb5SJens Wiklander
141ac17bb5SJens Wiklander #include "acipher_helpers.h"
151ac17bb5SJens Wiklander
crypto_acipher_alloc_dsa_keypair(struct dsa_keypair * s,size_t key_size_bits __unused)161ac17bb5SJens Wiklander TEE_Result crypto_acipher_alloc_dsa_keypair(struct dsa_keypair *s,
171ac17bb5SJens Wiklander size_t key_size_bits __unused)
181ac17bb5SJens Wiklander {
191ac17bb5SJens Wiklander memset(s, 0, sizeof(*s));
201ac17bb5SJens Wiklander if (!bn_alloc_max(&s->g))
211ac17bb5SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
221ac17bb5SJens Wiklander
231ac17bb5SJens Wiklander if (!bn_alloc_max(&s->p))
241ac17bb5SJens Wiklander goto err;
251ac17bb5SJens Wiklander if (!bn_alloc_max(&s->q))
261ac17bb5SJens Wiklander goto err;
271ac17bb5SJens Wiklander if (!bn_alloc_max(&s->y))
281ac17bb5SJens Wiklander goto err;
291ac17bb5SJens Wiklander if (!bn_alloc_max(&s->x))
301ac17bb5SJens Wiklander goto err;
311ac17bb5SJens Wiklander return TEE_SUCCESS;
321ac17bb5SJens Wiklander err:
33*e2ec831cSJihwan Park crypto_bignum_free(&s->g);
34*e2ec831cSJihwan Park crypto_bignum_free(&s->p);
35*e2ec831cSJihwan Park crypto_bignum_free(&s->q);
36*e2ec831cSJihwan Park crypto_bignum_free(&s->y);
371ac17bb5SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
381ac17bb5SJens Wiklander }
391ac17bb5SJens Wiklander
crypto_acipher_alloc_dsa_public_key(struct dsa_public_key * s,size_t key_size_bits __unused)401ac17bb5SJens Wiklander TEE_Result crypto_acipher_alloc_dsa_public_key(struct dsa_public_key *s,
411ac17bb5SJens Wiklander size_t key_size_bits __unused)
421ac17bb5SJens Wiklander {
431ac17bb5SJens Wiklander memset(s, 0, sizeof(*s));
441ac17bb5SJens Wiklander if (!bn_alloc_max(&s->g))
451ac17bb5SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
461ac17bb5SJens Wiklander
471ac17bb5SJens Wiklander if (!bn_alloc_max(&s->p))
481ac17bb5SJens Wiklander goto err;
491ac17bb5SJens Wiklander if (!bn_alloc_max(&s->q))
501ac17bb5SJens Wiklander goto err;
511ac17bb5SJens Wiklander if (!bn_alloc_max(&s->y))
521ac17bb5SJens Wiklander goto err;
531ac17bb5SJens Wiklander return TEE_SUCCESS;
541ac17bb5SJens Wiklander err:
55*e2ec831cSJihwan Park crypto_bignum_free(&s->g);
56*e2ec831cSJihwan Park crypto_bignum_free(&s->p);
57*e2ec831cSJihwan Park crypto_bignum_free(&s->q);
581ac17bb5SJens Wiklander return TEE_ERROR_OUT_OF_MEMORY;
591ac17bb5SJens Wiklander }
601ac17bb5SJens Wiklander
crypto_acipher_gen_dsa_key(struct dsa_keypair * key,size_t key_size)611ac17bb5SJens Wiklander TEE_Result crypto_acipher_gen_dsa_key(struct dsa_keypair *key, size_t key_size)
621ac17bb5SJens Wiklander {
6382c30aaaSJerome Forissier dsa_key ltc_tmp_key = { };
6482c30aaaSJerome Forissier int ltc_res = 0;
651ac17bb5SJens Wiklander
6682c30aaaSJerome Forissier if (key_size != 8 * mp_unsigned_bin_size(key->p))
6782c30aaaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
6882c30aaaSJerome Forissier
6982c30aaaSJerome Forissier ltc_res = mp_init_multi(<c_tmp_key.g, <c_tmp_key.p, <c_tmp_key.q,
7082c30aaaSJerome Forissier <c_tmp_key.x, <c_tmp_key.y, NULL);
7182c30aaaSJerome Forissier if (ltc_res)
7282c30aaaSJerome Forissier return TEE_ERROR_OUT_OF_MEMORY;
7382c30aaaSJerome Forissier
7482c30aaaSJerome Forissier /* Copy the key parameters */
7582c30aaaSJerome Forissier mp_copy(key->g, ltc_tmp_key.g);
7682c30aaaSJerome Forissier mp_copy(key->p, ltc_tmp_key.p);
7782c30aaaSJerome Forissier mp_copy(key->q, ltc_tmp_key.q);
781ac17bb5SJens Wiklander
791ac17bb5SJens Wiklander /* Generate the DSA key */
8082c30aaaSJerome Forissier ltc_res = dsa_generate_key(NULL, find_prng("prng_crypto"),
8182c30aaaSJerome Forissier <c_tmp_key);
8282c30aaaSJerome Forissier if (ltc_res)
8382c30aaaSJerome Forissier return TEE_ERROR_BAD_PARAMETERS;
841ac17bb5SJens Wiklander
8582c30aaaSJerome Forissier /* Copy the key */
8682c30aaaSJerome Forissier mp_copy(ltc_tmp_key.y, key->y);
8782c30aaaSJerome Forissier mp_copy(ltc_tmp_key.x, key->x);
8882c30aaaSJerome Forissier
8982c30aaaSJerome Forissier /* Free the temporary key */
901ac17bb5SJens Wiklander dsa_free(<c_tmp_key);
9182c30aaaSJerome Forissier
9282c30aaaSJerome Forissier return TEE_SUCCESS;
931ac17bb5SJens Wiklander }
941ac17bb5SJens Wiklander
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)951ac17bb5SJens Wiklander TEE_Result crypto_acipher_dsa_sign(uint32_t algo, struct dsa_keypair *key,
961ac17bb5SJens Wiklander const uint8_t *msg, size_t msg_len,
971ac17bb5SJens Wiklander uint8_t *sig, size_t *sig_len)
981ac17bb5SJens Wiklander {
991ac17bb5SJens Wiklander TEE_Result res;
1001ac17bb5SJens Wiklander size_t hash_size;
1011ac17bb5SJens Wiklander int ltc_res;
1021ac17bb5SJens Wiklander void *r, *s;
1031ac17bb5SJens Wiklander dsa_key ltc_key = {
1041ac17bb5SJens Wiklander .type = PK_PRIVATE,
1058411e6adSJerome Forissier .qord = mp_unsigned_bin_size(key->q),
1061ac17bb5SJens Wiklander .g = key->g,
1071ac17bb5SJens Wiklander .p = key->p,
1081ac17bb5SJens Wiklander .q = key->q,
1091ac17bb5SJens Wiklander .y = key->y,
1101ac17bb5SJens Wiklander .x = key->x,
1111ac17bb5SJens Wiklander };
1121ac17bb5SJens Wiklander
1131ac17bb5SJens Wiklander if (algo != TEE_ALG_DSA_SHA1 &&
1141ac17bb5SJens Wiklander algo != TEE_ALG_DSA_SHA224 &&
1151ac17bb5SJens Wiklander algo != TEE_ALG_DSA_SHA256) {
1161ac17bb5SJens Wiklander res = TEE_ERROR_NOT_IMPLEMENTED;
1171ac17bb5SJens Wiklander goto err;
1181ac17bb5SJens Wiklander }
1191ac17bb5SJens Wiklander
1207c767434SAlbert Schwarzkopf res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo),
1211ac17bb5SJens Wiklander &hash_size);
1221ac17bb5SJens Wiklander if (res != TEE_SUCCESS)
1231ac17bb5SJens Wiklander goto err;
1241ac17bb5SJens Wiklander if (mp_unsigned_bin_size(ltc_key.q) < hash_size)
1251ac17bb5SJens Wiklander hash_size = mp_unsigned_bin_size(ltc_key.q);
1261ac17bb5SJens Wiklander if (msg_len != hash_size) {
1271ac17bb5SJens Wiklander res = TEE_ERROR_SECURITY;
1281ac17bb5SJens Wiklander goto err;
1291ac17bb5SJens Wiklander }
1301ac17bb5SJens Wiklander
1311ac17bb5SJens Wiklander if (*sig_len < 2 * mp_unsigned_bin_size(ltc_key.q)) {
1321ac17bb5SJens Wiklander *sig_len = 2 * mp_unsigned_bin_size(ltc_key.q);
1331ac17bb5SJens Wiklander res = TEE_ERROR_SHORT_BUFFER;
1341ac17bb5SJens Wiklander goto err;
1351ac17bb5SJens Wiklander }
1361ac17bb5SJens Wiklander
1371ac17bb5SJens Wiklander ltc_res = mp_init_multi(&r, &s, NULL);
1381ac17bb5SJens Wiklander if (ltc_res != CRYPT_OK) {
1391ac17bb5SJens Wiklander res = TEE_ERROR_OUT_OF_MEMORY;
1401ac17bb5SJens Wiklander goto err;
1411ac17bb5SJens Wiklander }
1421ac17bb5SJens Wiklander
1431ac17bb5SJens Wiklander ltc_res = dsa_sign_hash_raw(msg, msg_len, r, s, NULL,
1441f3b1115SJens Wiklander find_prng("prng_crypto"), <c_key);
1451ac17bb5SJens Wiklander
1461ac17bb5SJens Wiklander if (ltc_res == CRYPT_OK) {
1471ac17bb5SJens Wiklander *sig_len = 2 * mp_unsigned_bin_size(ltc_key.q);
1481ac17bb5SJens Wiklander memset(sig, 0, *sig_len);
1491ac17bb5SJens Wiklander mp_to_unsigned_bin(r, (uint8_t *)sig + *sig_len/2 -
1501ac17bb5SJens Wiklander mp_unsigned_bin_size(r));
1511ac17bb5SJens Wiklander mp_to_unsigned_bin(s, (uint8_t *)sig + *sig_len -
1521ac17bb5SJens Wiklander mp_unsigned_bin_size(s));
1531ac17bb5SJens Wiklander res = TEE_SUCCESS;
1541ac17bb5SJens Wiklander } else {
1551ac17bb5SJens Wiklander res = TEE_ERROR_GENERIC;
1561ac17bb5SJens Wiklander }
1571ac17bb5SJens Wiklander
1581ac17bb5SJens Wiklander mp_clear_multi(r, s, NULL);
1591ac17bb5SJens Wiklander
1601ac17bb5SJens Wiklander err:
1611ac17bb5SJens Wiklander return res;
1621ac17bb5SJens Wiklander }
1631ac17bb5SJens Wiklander
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)1641ac17bb5SJens Wiklander TEE_Result crypto_acipher_dsa_verify(uint32_t algo, struct dsa_public_key *key,
1651ac17bb5SJens Wiklander const uint8_t *msg, size_t msg_len,
1661ac17bb5SJens Wiklander const uint8_t *sig, size_t sig_len)
1671ac17bb5SJens Wiklander {
1681ac17bb5SJens Wiklander TEE_Result res;
1691ac17bb5SJens Wiklander int ltc_stat, ltc_res;
1701ac17bb5SJens Wiklander void *r, *s;
1711ac17bb5SJens Wiklander dsa_key ltc_key = {
1721ac17bb5SJens Wiklander .type = PK_PUBLIC,
1738411e6adSJerome Forissier .qord = mp_unsigned_bin_size(key->q),
1741ac17bb5SJens Wiklander .g = key->g,
1751ac17bb5SJens Wiklander .p = key->p,
1761ac17bb5SJens Wiklander .q = key->q,
1771ac17bb5SJens Wiklander .y = key->y
1781ac17bb5SJens Wiklander };
1791ac17bb5SJens Wiklander
1801ac17bb5SJens Wiklander if (algo != TEE_ALG_DSA_SHA1 &&
1811ac17bb5SJens Wiklander algo != TEE_ALG_DSA_SHA224 &&
1821ac17bb5SJens Wiklander algo != TEE_ALG_DSA_SHA256) {
1831ac17bb5SJens Wiklander res = TEE_ERROR_NOT_IMPLEMENTED;
1841ac17bb5SJens Wiklander goto err;
1851ac17bb5SJens Wiklander }
1861ac17bb5SJens Wiklander
1871ac17bb5SJens Wiklander ltc_res = mp_init_multi(&r, &s, NULL);
1881ac17bb5SJens Wiklander if (ltc_res != CRYPT_OK) {
1891ac17bb5SJens Wiklander res = TEE_ERROR_OUT_OF_MEMORY;
1901ac17bb5SJens Wiklander goto err;
1911ac17bb5SJens Wiklander }
1921ac17bb5SJens Wiklander mp_read_unsigned_bin(r, (uint8_t *)sig, sig_len/2);
1931ac17bb5SJens Wiklander mp_read_unsigned_bin(s, (uint8_t *)sig + sig_len/2, sig_len/2);
1941ac17bb5SJens Wiklander ltc_res = dsa_verify_hash_raw(r, s, msg, msg_len, <c_stat, <c_key);
1951ac17bb5SJens Wiklander mp_clear_multi(r, s, NULL);
1961ac17bb5SJens Wiklander res = convert_ltc_verify_status(ltc_res, ltc_stat);
1971ac17bb5SJens Wiklander err:
1981ac17bb5SJens Wiklander return res;
1991ac17bb5SJens Wiklander }
200