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