1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2018-2021 NXP
4  *
5  * Crypto DSA interface implementation to enable HW driver.
6  */
7 #include <crypto/crypto.h>
8 #include <drvcrypt.h>
9 #include <drvcrypt_acipher.h>
10 
11 /*
12  * Get the recommended L and N bits parameters corresponding
13  * respectively to the size of the Primes P and G (and so
14  * the Public Key and Private Key).
15  *
16  * Refer the NIST.FIPS 186-4 section 4.2
17  *
18  * @size_bits   Maximum key size bits
19  * @l_bits      [out] L size in bits
20  * @n_bits      [out] N size in bits
21  */
get_keys_size(size_t size_bits,size_t * l_bits,size_t * n_bits)22 static TEE_Result get_keys_size(size_t size_bits, size_t *l_bits,
23 				size_t *n_bits)
24 {
25 	if (size_bits <= 1024)
26 		*n_bits = 160;
27 	else if (size_bits <= 3072)
28 		*n_bits = 256;
29 	else
30 		return TEE_ERROR_NOT_IMPLEMENTED;
31 
32 	*l_bits = size_bits;
33 
34 	return TEE_SUCCESS;
35 }
36 
crypto_acipher_alloc_dsa_keypair(struct dsa_keypair * key,size_t size_bits)37 TEE_Result crypto_acipher_alloc_dsa_keypair(struct dsa_keypair *key,
38 					    size_t size_bits)
39 {
40 	TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
41 	struct drvcrypt_dsa *dsa = NULL;
42 	size_t l_bits = 0;
43 	size_t n_bits = 0;
44 
45 	if (!key || !size_bits) {
46 		CRYPTO_TRACE("Param error key @0x%" PRIxPTR " size %zu bits",
47 			     (uintptr_t)key, size_bits);
48 		return TEE_ERROR_BAD_PARAMETERS;
49 	}
50 
51 	ret = get_keys_size(size_bits, &l_bits, &n_bits);
52 	if (ret == TEE_SUCCESS) {
53 		dsa = drvcrypt_get_ops(CRYPTO_DSA);
54 		if (dsa)
55 			ret = dsa->alloc_keypair(key, l_bits, n_bits);
56 		else
57 			ret = TEE_ERROR_NOT_IMPLEMENTED;
58 	}
59 
60 	CRYPTO_TRACE("DSA Keypair (%zu bits) alloc ret = 0x%" PRIx32, size_bits,
61 		     ret);
62 	return ret;
63 }
64 
crypto_acipher_alloc_dsa_public_key(struct dsa_public_key * key,size_t size_bits)65 TEE_Result crypto_acipher_alloc_dsa_public_key(struct dsa_public_key *key,
66 					       size_t size_bits)
67 {
68 	TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
69 	struct drvcrypt_dsa *dsa = NULL;
70 	size_t l_bits = 0;
71 	size_t n_bits = 0;
72 
73 	if (!key || !size_bits) {
74 		CRYPTO_TRACE("Param error key @0x%" PRIxPTR " size %zu bits",
75 			     (uintptr_t)key, size_bits);
76 		return TEE_ERROR_BAD_PARAMETERS;
77 	}
78 
79 	ret = get_keys_size(size_bits, &l_bits, &n_bits);
80 	if (ret == TEE_SUCCESS) {
81 		dsa = drvcrypt_get_ops(CRYPTO_DSA);
82 		if (dsa)
83 			ret = dsa->alloc_publickey(key, l_bits, n_bits);
84 		else
85 			ret = TEE_ERROR_NOT_IMPLEMENTED;
86 	}
87 
88 	CRYPTO_TRACE("DSA Public Key (%zu bits) alloc ret = 0x%" PRIx32,
89 		     size_bits, ret);
90 	return ret;
91 }
92 
crypto_acipher_gen_dsa_key(struct dsa_keypair * key,size_t key_size)93 TEE_Result crypto_acipher_gen_dsa_key(struct dsa_keypair *key, size_t key_size)
94 {
95 	TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
96 	struct drvcrypt_dsa *dsa = NULL;
97 	size_t l_bits = 0;
98 	size_t n_bits = 0;
99 
100 	if (!key || !key_size) {
101 		CRYPTO_TRACE("Param error key @0x%" PRIxPTR " size %zu bits",
102 			     (uintptr_t)key, key_size);
103 		return TEE_ERROR_BAD_PARAMETERS;
104 	}
105 
106 	ret = get_keys_size(key_size, &l_bits, &n_bits);
107 	if (ret == TEE_SUCCESS) {
108 		dsa = drvcrypt_get_ops(CRYPTO_DSA);
109 		if (dsa)
110 			ret = dsa->gen_keypair(key, l_bits, n_bits);
111 		else
112 			ret = TEE_ERROR_NOT_IMPLEMENTED;
113 	}
114 
115 	CRYPTO_TRACE("DSA Keypair (%zu bits) generate ret = 0x%" PRIx32,
116 		     key_size, ret);
117 
118 	return ret;
119 }
120 
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)121 TEE_Result crypto_acipher_dsa_sign(uint32_t algo, struct dsa_keypair *key,
122 				   const uint8_t *msg, size_t msg_len,
123 				   uint8_t *sig, size_t *sig_len)
124 {
125 	TEE_Result ret = TEE_ERROR_BAD_PARAMETERS;
126 	struct drvcrypt_dsa *dsa = NULL;
127 	struct drvcrypt_sign_data sdata = { };
128 	size_t l_bytes = 0;
129 	size_t n_bytes = 0;
130 
131 	if (!key || !msg || !sig_len) {
132 		CRYPTO_TRACE("Input parameters reference error");
133 		return TEE_ERROR_BAD_PARAMETERS;
134 	}
135 
136 	/*
137 	 * Verify the signature length function of the key size
138 	 *
139 	 * Prime number sizes are not stored but deducted from bignum size.
140 	 * This requires prime numbers p and q to have their MSB set otherwise
141 	 * crypto_bignum_num_bytes() will return a wrong size.
142 	 */
143 	n_bytes = crypto_bignum_num_bytes(key->q);
144 	l_bytes = crypto_bignum_num_bytes(key->p);
145 	if (*sig_len < 2 * n_bytes) {
146 		CRYPTO_TRACE("Length (%zu) too short expected %zu bytes",
147 			     *sig_len, 2 * n_bytes);
148 		*sig_len = 2 * n_bytes;
149 		return TEE_ERROR_SHORT_BUFFER;
150 	}
151 
152 	if (!sig) {
153 		CRYPTO_TRACE("Parameter \"sig\" reference error");
154 		return TEE_ERROR_BAD_PARAMETERS;
155 	}
156 
157 	dsa = drvcrypt_get_ops(CRYPTO_DSA);
158 	if (dsa) {
159 		sdata.algo = algo;
160 		sdata.key = key;
161 		sdata.size_sec = n_bytes;
162 		sdata.message.data = (uint8_t *)msg;
163 		sdata.message.length = msg_len;
164 		sdata.signature.data = sig;
165 		sdata.signature.length = *sig_len;
166 
167 		ret = dsa->sign(&sdata, l_bytes, n_bytes);
168 
169 		/* Set the signature length */
170 		*sig_len = sdata.signature.length;
171 	} else {
172 		ret = TEE_ERROR_NOT_IMPLEMENTED;
173 	}
174 
175 	CRYPTO_TRACE("Sign algo (0x%" PRIx32 ") returned 0x%" PRIx32, algo,
176 		     ret);
177 
178 	return ret;
179 }
180 
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)181 TEE_Result crypto_acipher_dsa_verify(uint32_t algo, struct dsa_public_key *key,
182 				     const uint8_t *msg, size_t msg_len,
183 				     const uint8_t *sig, size_t sig_len)
184 {
185 	TEE_Result ret = TEE_ERROR_BAD_PARAMETERS;
186 	struct drvcrypt_dsa *dsa = NULL;
187 	struct drvcrypt_sign_data sdata = { };
188 	size_t l_bytes = 0;
189 	size_t n_bytes = 0;
190 
191 	if (!key || !msg || !sig) {
192 		CRYPTO_TRACE("Input parameters reference error");
193 		return TEE_ERROR_BAD_PARAMETERS;
194 	}
195 
196 	/*
197 	 * Verify the signature length function of the key size
198 	 *
199 	 * Prime number sizes are not stored but deducted from bignum size.
200 	 * This requires prime numbers p and q to have their MSB set otherwise
201 	 * crypto_bignum_num_bytes() will return a wrong size.
202 	 */
203 	n_bytes = crypto_bignum_num_bytes(key->q);
204 	l_bytes = crypto_bignum_num_bytes(key->p);
205 	if (sig_len != 2 * n_bytes) {
206 		CRYPTO_TRACE("Length (%zu) is invalid expected %zu bytes",
207 			     sig_len, 2 * n_bytes);
208 		return TEE_ERROR_SIGNATURE_INVALID;
209 	}
210 
211 	dsa = drvcrypt_get_ops(CRYPTO_DSA);
212 	if (dsa) {
213 		sdata.algo = algo;
214 		sdata.key = key;
215 		sdata.size_sec = n_bytes;
216 		sdata.message.data = (uint8_t *)msg;
217 		sdata.message.length = msg_len;
218 		sdata.signature.data = (uint8_t *)sig;
219 		sdata.signature.length = sig_len;
220 
221 		ret = dsa->verify(&sdata, l_bytes, n_bytes);
222 	} else {
223 		ret = TEE_ERROR_NOT_IMPLEMENTED;
224 	}
225 
226 	CRYPTO_TRACE("Verify algo (0x%" PRIx32 ") returned 0x%" PRIx32, algo,
227 		     ret);
228 
229 	return ret;
230 }
231