1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2022, Technology Innovation Institute (TII)
4  * Copyright (c) 2022, EPAM Systems
5  */
6 
7 #include <crypto/crypto.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <string_ext.h>
11 #include <tee_api_types.h>
12 #include <trace.h>
13 #include <utee_defines.h>
14 
15 #include "acipher_helpers.h"
16 
17 #define ED25519_KEY_SIZE UL(256)
18 
crypto_acipher_alloc_ed25519_keypair(struct ed25519_keypair * key,size_t key_size)19 TEE_Result crypto_acipher_alloc_ed25519_keypair(struct ed25519_keypair *key,
20 						size_t key_size)
21 {
22 	if (!key || key_size != ED25519_KEY_SIZE)
23 		return TEE_ERROR_BAD_PARAMETERS;
24 
25 	memset(key, 0, sizeof(*key));
26 
27 	key->priv = calloc(1, key_size >> 3);
28 	key->pub = calloc(1, key_size >> 3);
29 
30 	if (!key->priv || !key->pub) {
31 		free(key->priv);
32 		free(key->pub);
33 		return TEE_ERROR_OUT_OF_MEMORY;
34 	}
35 
36 	return TEE_SUCCESS;
37 }
38 
39 TEE_Result
crypto_acipher_alloc_ed25519_public_key(struct ed25519_public_key * key,size_t key_size)40 crypto_acipher_alloc_ed25519_public_key(struct ed25519_public_key *key,
41 					size_t key_size)
42 {
43 	if (!key || key_size != ED25519_KEY_SIZE)
44 		return TEE_ERROR_BAD_PARAMETERS;
45 
46 	memset(key, 0, sizeof(*key));
47 
48 	key->pub = calloc(1, key_size >> 3);
49 
50 	if (!key->pub)
51 		return TEE_ERROR_OUT_OF_MEMORY;
52 
53 	return TEE_SUCCESS;
54 }
55 
crypto_acipher_gen_ed25519_key(struct ed25519_keypair * key,size_t key_size)56 TEE_Result crypto_acipher_gen_ed25519_key(struct ed25519_keypair *key,
57 					  size_t key_size)
58 {
59 	curve25519_key ltc_tmp_key = { };
60 
61 	if (key_size != ED25519_KEY_SIZE)
62 		return TEE_ERROR_BAD_PARAMETERS;
63 
64 	if (ed25519_make_key(NULL, find_prng("prng_crypto"),
65 			     &ltc_tmp_key) != CRYPT_OK)
66 		return TEE_ERROR_BAD_PARAMETERS;
67 
68 	assert(key_size >= sizeof(ltc_tmp_key.pub) &&
69 	       key_size >= sizeof(ltc_tmp_key.priv));
70 
71 	memcpy(key->pub, ltc_tmp_key.pub, sizeof(ltc_tmp_key.pub));
72 	memcpy(key->priv, ltc_tmp_key.priv, sizeof(ltc_tmp_key.priv));
73 	memzero_explicit(&ltc_tmp_key, sizeof(ltc_tmp_key));
74 
75 	return TEE_SUCCESS;
76 }
77 
crypto_acipher_ed25519_sign(struct ed25519_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)78 TEE_Result crypto_acipher_ed25519_sign(struct ed25519_keypair *key,
79 				       const uint8_t *msg, size_t msg_len,
80 				       uint8_t *sig, size_t *sig_len)
81 {
82 	int err;
83 	unsigned long siglen = 0;
84 	curve25519_key private_key = {
85 		.type = PK_PRIVATE,
86 		.algo = LTC_OID_ED25519,
87 	};
88 
89 	if (!key || !sig_len)
90 		return TEE_ERROR_BAD_PARAMETERS;
91 
92 	if (*sig_len < UL(64)) {
93 		*sig_len = UL(64);
94 		return TEE_ERROR_SHORT_BUFFER;
95 	}
96 
97 	siglen = *sig_len;
98 
99 	memcpy(private_key.priv, key->priv, sizeof(private_key.priv));
100 	memcpy(private_key.pub, key->pub, sizeof(private_key.pub));
101 
102 	err = ed25519_sign(msg, msg_len, sig, &siglen, &private_key);
103 
104 	memzero_explicit(&private_key, sizeof(private_key));
105 
106 	if (err != CRYPT_OK)
107 		return TEE_ERROR_BAD_PARAMETERS;
108 	*sig_len = siglen;
109 	return TEE_SUCCESS;
110 }
111 
crypto_acipher_ed25519ctx_sign(struct ed25519_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len,bool ph_flag,const uint8_t * ctx,size_t ctxlen)112 TEE_Result crypto_acipher_ed25519ctx_sign(struct ed25519_keypair *key,
113 					  const uint8_t *msg, size_t msg_len,
114 					  uint8_t *sig, size_t *sig_len,
115 					  bool ph_flag,
116 					  const uint8_t *ctx, size_t ctxlen)
117 {
118 	int err = CRYPT_ERROR;
119 	unsigned long siglen = 0;
120 	curve25519_key private_key = {
121 		.type = PK_PRIVATE,
122 		.algo = LTC_OID_ED25519,
123 	};
124 
125 	if (!key || !sig_len)
126 		return TEE_ERROR_BAD_PARAMETERS;
127 
128 	if (*sig_len < UL(64)) {
129 		*sig_len = UL(64);
130 		return TEE_ERROR_SHORT_BUFFER;
131 	}
132 
133 	siglen = *sig_len;
134 
135 	memcpy(private_key.priv, key->priv, sizeof(private_key.priv));
136 	memcpy(private_key.pub, key->pub, sizeof(private_key.pub));
137 
138 	if (ph_flag) {
139 		err = ed25519ph_sign(msg, msg_len, sig, &siglen,
140 				     ctx, ctxlen, &private_key);
141 	} else {
142 		err = ed25519ctx_sign(msg, msg_len, sig, &siglen,
143 				      ctx, ctxlen, &private_key);
144 	}
145 
146 	memzero_explicit(&private_key, sizeof(private_key));
147 
148 	if (err != CRYPT_OK)
149 		return TEE_ERROR_BAD_PARAMETERS;
150 	*sig_len = siglen;
151 	return TEE_SUCCESS;
152 }
153 
crypto_acipher_ed25519_verify(struct ed25519_public_key * key,const uint8_t * msg,size_t msg_len,const uint8_t * sig,size_t sig_len)154 TEE_Result crypto_acipher_ed25519_verify(struct ed25519_public_key *key,
155 					 const uint8_t *msg, size_t msg_len,
156 					 const uint8_t *sig, size_t sig_len)
157 {
158 	int stat = 0;
159 	curve25519_key public_key = {
160 		.type = PK_PUBLIC,
161 		.algo = LTC_OID_ED25519,
162 	};
163 
164 	if (!key)
165 		return TEE_ERROR_BAD_PARAMETERS;
166 
167 	memcpy(public_key.pub, key->pub, sizeof(public_key.pub));
168 
169 	if (ed25519_verify(msg, msg_len, sig, sig_len, &stat,
170 			   &public_key) != CRYPT_OK)
171 		return TEE_ERROR_BAD_PARAMETERS;
172 
173 	if (stat != 1)
174 		return TEE_ERROR_SIGNATURE_INVALID;
175 
176 	return TEE_SUCCESS;
177 }
178 
crypto_acipher_ed25519ctx_verify(struct ed25519_public_key * key,const uint8_t * msg,size_t msg_len,const uint8_t * sig,size_t sig_len,bool ph_flag,const uint8_t * ctx,size_t ctxlen)179 TEE_Result crypto_acipher_ed25519ctx_verify(struct ed25519_public_key *key,
180 					    const uint8_t *msg, size_t msg_len,
181 					    const uint8_t *sig, size_t sig_len,
182 					    bool ph_flag,
183 					    const uint8_t *ctx, size_t ctxlen)
184 {
185 	int stat = 0;
186 	curve25519_key public_key = {
187 		.type = PK_PUBLIC,
188 		.algo = LTC_OID_ED25519,
189 	};
190 
191 	if (!key)
192 		return TEE_ERROR_BAD_PARAMETERS;
193 
194 	memcpy(public_key.pub, key->pub, sizeof(public_key.pub));
195 
196 	if (ph_flag) {
197 		if (ed25519ph_verify(msg, msg_len, sig, sig_len, ctx, ctxlen,
198 				     &stat, &public_key) != CRYPT_OK)
199 			return TEE_ERROR_BAD_PARAMETERS;
200 	} else {
201 		if (ed25519ctx_verify(msg, msg_len, sig, sig_len, ctx, ctxlen,
202 				      &stat, &public_key) != CRYPT_OK)
203 			return TEE_ERROR_BAD_PARAMETERS;
204 	}
205 
206 	if (stat != 1)
207 		return TEE_ERROR_SIGNATURE_INVALID;
208 
209 	return TEE_SUCCESS;
210 }
211