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 
crypto_acipher_gen_ed25519_key(struct ed25519_keypair * key,size_t key_size)39 TEE_Result crypto_acipher_gen_ed25519_key(struct ed25519_keypair *key,
40 					  size_t key_size)
41 {
42 	curve25519_key ltc_tmp_key = { };
43 
44 	if (key_size != ED25519_KEY_SIZE)
45 		return TEE_ERROR_BAD_PARAMETERS;
46 
47 	if (ed25519_make_key(NULL, find_prng("prng_crypto"),
48 			     &ltc_tmp_key) != CRYPT_OK)
49 		return TEE_ERROR_BAD_PARAMETERS;
50 
51 	assert(key_size >= sizeof(ltc_tmp_key.pub) &&
52 	       key_size >= sizeof(ltc_tmp_key.priv));
53 
54 	memcpy(key->pub, ltc_tmp_key.pub, sizeof(ltc_tmp_key.pub));
55 	memcpy(key->priv, ltc_tmp_key.priv, sizeof(ltc_tmp_key.priv));
56 	memzero_explicit(&ltc_tmp_key, sizeof(ltc_tmp_key));
57 
58 	return TEE_SUCCESS;
59 }
60 
crypto_acipher_ed25519_sign(struct ed25519_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)61 TEE_Result crypto_acipher_ed25519_sign(struct ed25519_keypair *key,
62 				       const uint8_t *msg, size_t msg_len,
63 				       uint8_t *sig, size_t *sig_len)
64 {
65 	int err;
66 	unsigned long siglen = 0;
67 	curve25519_key private_key = {
68 		.type = PK_PRIVATE,
69 		.algo = LTC_OID_ED25519,
70 	};
71 
72 	if (!key || !sig_len)
73 		return TEE_ERROR_BAD_PARAMETERS;
74 
75 	siglen = *sig_len;
76 
77 	memcpy(private_key.priv, key->priv, sizeof(private_key.priv));
78 	memcpy(private_key.pub, key->pub, sizeof(private_key.pub));
79 
80 	err = ed25519_sign(msg, msg_len, sig, &siglen, &private_key);
81 
82 	memzero_explicit(&private_key, sizeof(private_key));
83 
84 	if (err != CRYPT_OK)
85 		return TEE_ERROR_BAD_PARAMETERS;
86 	*sig_len = siglen;
87 	return TEE_SUCCESS;
88 }
89 
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)90 TEE_Result crypto_acipher_ed25519ctx_sign(struct ed25519_keypair *key,
91 					  const uint8_t *msg, size_t msg_len,
92 					  uint8_t *sig, size_t *sig_len,
93 					  bool ph_flag,
94 					  const uint8_t *ctx, size_t ctxlen)
95 {
96 	int err = CRYPT_ERROR;
97 	unsigned long siglen = 0;
98 	curve25519_key private_key = {
99 		.type = PK_PRIVATE,
100 		.algo = LTC_OID_ED25519,
101 	};
102 
103 	if (!key || !sig_len)
104 		return TEE_ERROR_BAD_PARAMETERS;
105 
106 	siglen = *sig_len;
107 
108 	memcpy(private_key.priv, key->priv, sizeof(private_key.priv));
109 	memcpy(private_key.pub, key->pub, sizeof(private_key.pub));
110 
111 	if (ph_flag) {
112 		err = ed25519ph_sign(msg, msg_len, sig, &siglen,
113 				     ctx, ctxlen, &private_key);
114 	} else {
115 		err = ed25519ctx_sign(msg, msg_len, sig, &siglen,
116 				      ctx, ctxlen, &private_key);
117 	}
118 
119 	memzero_explicit(&private_key, sizeof(private_key));
120 
121 	if (err != CRYPT_OK)
122 		return TEE_ERROR_BAD_PARAMETERS;
123 	*sig_len = siglen;
124 	return TEE_SUCCESS;
125 }
126 
crypto_acipher_ed25519_verify(struct ed25519_keypair * key,const uint8_t * msg,size_t msg_len,const uint8_t * sig,size_t sig_len)127 TEE_Result crypto_acipher_ed25519_verify(struct ed25519_keypair *key,
128 					 const uint8_t *msg, size_t msg_len,
129 					 const uint8_t *sig, size_t sig_len)
130 {
131 	int stat = 0;
132 	curve25519_key public_key = {
133 		.type = PK_PUBLIC,
134 		.algo = LTC_OID_ED25519,
135 	};
136 
137 	if (!key)
138 		return TEE_ERROR_BAD_PARAMETERS;
139 
140 	memcpy(public_key.pub, key->pub, sizeof(public_key.pub));
141 
142 	if (ed25519_verify(msg, msg_len, sig, sig_len, &stat,
143 			   &public_key) != CRYPT_OK)
144 		return TEE_ERROR_BAD_PARAMETERS;
145 
146 	if (stat != 1)
147 		return TEE_ERROR_SIGNATURE_INVALID;
148 
149 	return TEE_SUCCESS;
150 }
151 
crypto_acipher_ed25519ctx_verify(struct ed25519_keypair * 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)152 TEE_Result crypto_acipher_ed25519ctx_verify(struct ed25519_keypair *key,
153 					    const uint8_t *msg, size_t msg_len,
154 					    const uint8_t *sig, size_t sig_len,
155 					    bool ph_flag,
156 					    const uint8_t *ctx, size_t ctxlen)
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 (ph_flag) {
170 		if (ed25519ph_verify(msg, msg_len, sig, sig_len, ctx, ctxlen,
171 				     &stat, &public_key) != CRYPT_OK)
172 			return TEE_ERROR_BAD_PARAMETERS;
173 	} else {
174 		if (ed25519ctx_verify(msg, msg_len, sig, sig_len, ctx, ctxlen,
175 				      &stat, &public_key) != CRYPT_OK)
176 			return TEE_ERROR_BAD_PARAMETERS;
177 	}
178 
179 	if (stat != 1)
180 		return TEE_ERROR_SIGNATURE_INVALID;
181 
182 	return TEE_SUCCESS;
183 }
184