xref: /optee_os/core/lib/libtomcrypt/dsa.c (revision 7c76743463bc33bcc058f7d8f745fb04fcfc95ee)
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 
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 
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 
61 TEE_Result crypto_acipher_gen_dsa_key(struct dsa_keypair *key, size_t key_size)
62 {
63 	TEE_Result res;
64 	dsa_key ltc_tmp_key;
65 	size_t group_size, modulus_size = key_size/8;
66 	int ltc_res;
67 
68 	if (modulus_size <= 128)
69 		group_size = 20;
70 	else if (modulus_size <= 256)
71 		group_size = 30;
72 	else if (modulus_size <= 384)
73 		group_size = 35;
74 	else
75 		group_size = 40;
76 
77 	/* Generate the DSA key */
78 	ltc_res = dsa_make_key(NULL, find_prng("prng_crypto"), group_size,
79 			       modulus_size, &ltc_tmp_key);
80 	if (ltc_res != CRYPT_OK) {
81 		res = TEE_ERROR_BAD_PARAMETERS;
82 	} else if ((size_t)mp_count_bits(ltc_tmp_key.p) != key_size) {
83 		dsa_free(&ltc_tmp_key);
84 		res = TEE_ERROR_BAD_PARAMETERS;
85 	} else {
86 		/* Copy the key */
87 		ltc_mp.copy(ltc_tmp_key.g, key->g);
88 		ltc_mp.copy(ltc_tmp_key.p, key->p);
89 		ltc_mp.copy(ltc_tmp_key.q, key->q);
90 		ltc_mp.copy(ltc_tmp_key.y, key->y);
91 		ltc_mp.copy(ltc_tmp_key.x, key->x);
92 
93 		/* Free the tempory key */
94 		dsa_free(&ltc_tmp_key);
95 		res = TEE_SUCCESS;
96 	}
97 	return res;
98 }
99 
100 TEE_Result crypto_acipher_dsa_sign(uint32_t algo, struct dsa_keypair *key,
101 				   const uint8_t *msg, size_t msg_len,
102 				   uint8_t *sig, size_t *sig_len)
103 {
104 	TEE_Result res;
105 	size_t hash_size;
106 	int ltc_res;
107 	void *r, *s;
108 	dsa_key ltc_key = {
109 		.type = PK_PRIVATE,
110 		.qord = mp_unsigned_bin_size(key->g),
111 		.g = key->g,
112 		.p = key->p,
113 		.q = key->q,
114 		.y = key->y,
115 		.x = key->x,
116 	};
117 
118 	if (algo != TEE_ALG_DSA_SHA1 &&
119 	    algo != TEE_ALG_DSA_SHA224 &&
120 	    algo != TEE_ALG_DSA_SHA256) {
121 		res = TEE_ERROR_NOT_IMPLEMENTED;
122 		goto err;
123 	}
124 
125 	res = tee_alg_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(algo),
126 				      &hash_size);
127 	if (res != TEE_SUCCESS)
128 		goto err;
129 	if (mp_unsigned_bin_size(ltc_key.q) < hash_size)
130 		hash_size = mp_unsigned_bin_size(ltc_key.q);
131 	if (msg_len != hash_size) {
132 		res = TEE_ERROR_SECURITY;
133 		goto err;
134 	}
135 
136 	if (*sig_len < 2 * mp_unsigned_bin_size(ltc_key.q)) {
137 		*sig_len = 2 * mp_unsigned_bin_size(ltc_key.q);
138 		res = TEE_ERROR_SHORT_BUFFER;
139 		goto err;
140 	}
141 
142 	ltc_res = mp_init_multi(&r, &s, NULL);
143 	if (ltc_res != CRYPT_OK) {
144 		res = TEE_ERROR_OUT_OF_MEMORY;
145 		goto err;
146 	}
147 
148 	ltc_res = dsa_sign_hash_raw(msg, msg_len, r, s, NULL,
149 				    find_prng("prng_crypto"), &ltc_key);
150 
151 	if (ltc_res == CRYPT_OK) {
152 		*sig_len = 2 * mp_unsigned_bin_size(ltc_key.q);
153 		memset(sig, 0, *sig_len);
154 		mp_to_unsigned_bin(r, (uint8_t *)sig + *sig_len/2 -
155 				   mp_unsigned_bin_size(r));
156 		mp_to_unsigned_bin(s, (uint8_t *)sig + *sig_len -
157 				   mp_unsigned_bin_size(s));
158 		res = TEE_SUCCESS;
159 	} else {
160 		res = TEE_ERROR_GENERIC;
161 	}
162 
163 	mp_clear_multi(r, s, NULL);
164 
165 err:
166 	return res;
167 }
168 
169 TEE_Result crypto_acipher_dsa_verify(uint32_t algo, struct dsa_public_key *key,
170 				     const uint8_t *msg, size_t msg_len,
171 				     const uint8_t *sig, size_t sig_len)
172 {
173 	TEE_Result res;
174 	int ltc_stat, ltc_res;
175 	void *r, *s;
176 	dsa_key ltc_key = {
177 		.type = PK_PUBLIC,
178 		.qord = mp_unsigned_bin_size(key->g),
179 		.g = key->g,
180 		.p = key->p,
181 		.q = key->q,
182 		.y = key->y
183 	};
184 
185 	if (algo != TEE_ALG_DSA_SHA1 &&
186 	    algo != TEE_ALG_DSA_SHA224 &&
187 	    algo != TEE_ALG_DSA_SHA256) {
188 		res = TEE_ERROR_NOT_IMPLEMENTED;
189 		goto err;
190 	}
191 
192 	ltc_res = mp_init_multi(&r, &s, NULL);
193 	if (ltc_res != CRYPT_OK) {
194 		res = TEE_ERROR_OUT_OF_MEMORY;
195 		goto err;
196 	}
197 	mp_read_unsigned_bin(r, (uint8_t *)sig, sig_len/2);
198 	mp_read_unsigned_bin(s, (uint8_t *)sig + sig_len/2, sig_len/2);
199 	ltc_res = dsa_verify_hash_raw(r, s, msg, msg_len, &ltc_stat, &ltc_key);
200 	mp_clear_multi(r, s, NULL);
201 	res = convert_ltc_verify_status(ltc_res, ltc_stat);
202 err:
203 	return res;
204 }
205