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 <c_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(<c_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