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