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(<c_tmp_key.g, <c_tmp_key.p, <c_tmp_key.q,
70 <c_tmp_key.x, <c_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 <c_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(<c_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->g),
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"), <c_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->g),
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, <c_stat, <c_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