1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014-2019, Linaro Limited
4  */
5 
6 #include <crypto/crypto.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <tee_api_types.h>
10 #include <tee/tee_cryp_utl.h>
11 #include <trace.h>
12 #include <utee_defines.h>
13 
14 #include "acipher_helpers.h"
15 
crypto_acipher_alloc_dsa_keypair(struct dsa_keypair * s,size_t key_size_bits __unused)16 TEE_Result crypto_acipher_alloc_dsa_keypair(struct dsa_keypair *s,
17 					    size_t key_size_bits __unused)
18 {
19 	memset(s, 0, sizeof(*s));
20 	if (!bn_alloc_max(&s->g))
21 		return TEE_ERROR_OUT_OF_MEMORY;
22 
23 	if (!bn_alloc_max(&s->p))
24 		goto err;
25 	if (!bn_alloc_max(&s->q))
26 		goto err;
27 	if (!bn_alloc_max(&s->y))
28 		goto err;
29 	if (!bn_alloc_max(&s->x))
30 		goto err;
31 	return TEE_SUCCESS;
32 err:
33 	crypto_bignum_free(s->g);
34 	crypto_bignum_free(s->p);
35 	crypto_bignum_free(s->q);
36 	crypto_bignum_free(s->y);
37 	return TEE_ERROR_OUT_OF_MEMORY;
38 }
39 
crypto_acipher_alloc_dsa_public_key(struct dsa_public_key * s,size_t key_size_bits __unused)40 TEE_Result crypto_acipher_alloc_dsa_public_key(struct dsa_public_key *s,
41 					       size_t key_size_bits __unused)
42 {
43 	memset(s, 0, sizeof(*s));
44 	if (!bn_alloc_max(&s->g))
45 		return TEE_ERROR_OUT_OF_MEMORY;
46 
47 	if (!bn_alloc_max(&s->p))
48 		goto err;
49 	if (!bn_alloc_max(&s->q))
50 		goto err;
51 	if (!bn_alloc_max(&s->y))
52 		goto err;
53 	return TEE_SUCCESS;
54 err:
55 	crypto_bignum_free(s->g);
56 	crypto_bignum_free(s->p);
57 	crypto_bignum_free(s->q);
58 	return TEE_ERROR_OUT_OF_MEMORY;
59 }
60 
crypto_acipher_gen_dsa_key(struct dsa_keypair * key,size_t key_size)61 TEE_Result crypto_acipher_gen_dsa_key(struct dsa_keypair *key, size_t key_size)
62 {
63 	dsa_key ltc_tmp_key = { };
64 	int ltc_res = 0;
65 
66 	if (key_size != 8 * mp_unsigned_bin_size(key->p))
67 		return TEE_ERROR_BAD_PARAMETERS;
68 
69 	ltc_res = mp_init_multi(&ltc_tmp_key.g, &ltc_tmp_key.p, &ltc_tmp_key.q,
70 				&ltc_tmp_key.x, &ltc_tmp_key.y, NULL);
71 	if (ltc_res)
72 		return TEE_ERROR_OUT_OF_MEMORY;
73 
74 	/* Copy the key parameters */
75 	mp_copy(key->g, ltc_tmp_key.g);
76 	mp_copy(key->p, ltc_tmp_key.p);
77 	mp_copy(key->q, ltc_tmp_key.q);
78 
79 	/* Generate the DSA key */
80 	ltc_res = dsa_generate_key(NULL, find_prng("prng_crypto"),
81 				   &ltc_tmp_key);
82 	if (ltc_res)
83 		return TEE_ERROR_BAD_PARAMETERS;
84 
85 	/* Copy the key */
86 	mp_copy(ltc_tmp_key.y, key->y);
87 	mp_copy(ltc_tmp_key.x, key->x);
88 
89 	/* Free the temporary key */
90 	dsa_free(&ltc_tmp_key);
91 
92 	return TEE_SUCCESS;
93 }
94 
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)95 TEE_Result crypto_acipher_dsa_sign(uint32_t algo, struct dsa_keypair *key,
96 				   const uint8_t *msg, size_t msg_len,
97 				   uint8_t *sig, size_t *sig_len)
98 {
99 	TEE_Result res;
100 	size_t hash_size;
101 	int ltc_res;
102 	void *r, *s;
103 	dsa_key ltc_key = {
104 		.type = PK_PRIVATE,
105 		.qord = mp_unsigned_bin_size(key->q),
106 		.g = key->g,
107 		.p = key->p,
108 		.q = key->q,
109 		.y = key->y,
110 		.x = key->x,
111 	};
112 
113 	if (algo != TEE_ALG_DSA_SHA1 &&
114 	    algo != TEE_ALG_DSA_SHA224 &&
115 	    algo != TEE_ALG_DSA_SHA256) {
116 		res = TEE_ERROR_NOT_IMPLEMENTED;
117 		goto err;
118 	}
119 
120 	res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo),
121 				      &hash_size);
122 	if (res != TEE_SUCCESS)
123 		goto err;
124 	if (mp_unsigned_bin_size(ltc_key.q) < hash_size)
125 		hash_size = mp_unsigned_bin_size(ltc_key.q);
126 	if (msg_len != hash_size) {
127 		res = TEE_ERROR_SECURITY;
128 		goto err;
129 	}
130 
131 	if (*sig_len < 2 * mp_unsigned_bin_size(ltc_key.q)) {
132 		*sig_len = 2 * mp_unsigned_bin_size(ltc_key.q);
133 		res = TEE_ERROR_SHORT_BUFFER;
134 		goto err;
135 	}
136 
137 	ltc_res = mp_init_multi(&r, &s, NULL);
138 	if (ltc_res != CRYPT_OK) {
139 		res = TEE_ERROR_OUT_OF_MEMORY;
140 		goto err;
141 	}
142 
143 	ltc_res = dsa_sign_hash_raw(msg, msg_len, r, s, NULL,
144 				    find_prng("prng_crypto"), &ltc_key);
145 
146 	if (ltc_res == CRYPT_OK) {
147 		*sig_len = 2 * mp_unsigned_bin_size(ltc_key.q);
148 		memset(sig, 0, *sig_len);
149 		mp_to_unsigned_bin(r, (uint8_t *)sig + *sig_len/2 -
150 				   mp_unsigned_bin_size(r));
151 		mp_to_unsigned_bin(s, (uint8_t *)sig + *sig_len -
152 				   mp_unsigned_bin_size(s));
153 		res = TEE_SUCCESS;
154 	} else {
155 		res = TEE_ERROR_GENERIC;
156 	}
157 
158 	mp_clear_multi(r, s, NULL);
159 
160 err:
161 	return res;
162 }
163 
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)164 TEE_Result crypto_acipher_dsa_verify(uint32_t algo, struct dsa_public_key *key,
165 				     const uint8_t *msg, size_t msg_len,
166 				     const uint8_t *sig, size_t sig_len)
167 {
168 	TEE_Result res;
169 	int ltc_stat, ltc_res;
170 	void *r, *s;
171 	dsa_key ltc_key = {
172 		.type = PK_PUBLIC,
173 		.qord = mp_unsigned_bin_size(key->q),
174 		.g = key->g,
175 		.p = key->p,
176 		.q = key->q,
177 		.y = key->y
178 	};
179 
180 	if (algo != TEE_ALG_DSA_SHA1 &&
181 	    algo != TEE_ALG_DSA_SHA224 &&
182 	    algo != TEE_ALG_DSA_SHA256) {
183 		res = TEE_ERROR_NOT_IMPLEMENTED;
184 		goto err;
185 	}
186 
187 	ltc_res = mp_init_multi(&r, &s, NULL);
188 	if (ltc_res != CRYPT_OK) {
189 		res = TEE_ERROR_OUT_OF_MEMORY;
190 		goto err;
191 	}
192 	mp_read_unsigned_bin(r, (uint8_t *)sig, sig_len/2);
193 	mp_read_unsigned_bin(s, (uint8_t *)sig + sig_len/2, sig_len/2);
194 	ltc_res = dsa_verify_hash_raw(r, s, msg, msg_len, &ltc_stat, &ltc_key);
195 	mp_clear_multi(r, s, NULL);
196 	res = convert_ltc_verify_status(ltc_res, ltc_stat);
197 err:
198 	return res;
199 }
200