xref: /optee_os/core/lib/libtomcrypt/ed25519.c (revision a116848b51a2d071827dad4a46ec98a5316631d2)
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 
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_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 
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;
67 	curve25519_key private_key = {
68 		.type = PK_PRIVATE,
69 		.algo = LTC_OID_ED25519,
70 	};
71 
72 	if (!key)
73 		return TEE_ERROR_BAD_PARAMETERS;
74 
75 	memcpy(private_key.priv, key->priv, sizeof(private_key.priv));
76 	memcpy(private_key.pub, key->pub, sizeof(private_key.pub));
77 
78 	err = ed25519_sign(msg, msg_len, sig, &siglen, &private_key);
79 
80 	memzero_explicit(&private_key, sizeof(private_key));
81 
82 	if (err != CRYPT_OK)
83 		return TEE_ERROR_BAD_PARAMETERS;
84 	*sig_len = siglen;
85 	return TEE_SUCCESS;
86 }
87 
88 TEE_Result crypto_acipher_ed25519ctx_sign(struct ed25519_keypair *key,
89 					  const uint8_t *msg, size_t msg_len,
90 					  uint8_t *sig, size_t *sig_len,
91 					  bool ph_flag,
92 					  const uint8_t *ctx, size_t ctxlen)
93 {
94 	int err = CRYPT_ERROR;
95 	unsigned long siglen;
96 	curve25519_key private_key = {
97 		.type = PK_PRIVATE,
98 		.algo = LTC_OID_ED25519,
99 	};
100 
101 	if (!key)
102 		return TEE_ERROR_BAD_PARAMETERS;
103 
104 	memcpy(private_key.priv, key->priv, sizeof(private_key.priv));
105 	memcpy(private_key.pub, key->pub, sizeof(private_key.pub));
106 
107 	if (ph_flag) {
108 		err = ed25519ph_sign(msg, msg_len, sig, &siglen,
109 				     ctx, ctxlen, &private_key);
110 	} else {
111 		err = ed25519ctx_sign(msg, msg_len, sig, &siglen,
112 				      ctx, ctxlen, &private_key);
113 	}
114 
115 	memzero_explicit(&private_key, sizeof(private_key));
116 
117 	if (err != CRYPT_OK)
118 		return TEE_ERROR_BAD_PARAMETERS;
119 	*sig_len = siglen;
120 	return TEE_SUCCESS;
121 }
122 
123 TEE_Result crypto_acipher_ed25519_verify(struct ed25519_keypair *key,
124 					 const uint8_t *msg, size_t msg_len,
125 					 const uint8_t *sig, size_t sig_len)
126 {
127 	int stat = 0;
128 	curve25519_key public_key = {
129 		.type = PK_PUBLIC,
130 		.algo = LTC_OID_ED25519,
131 	};
132 
133 	if (!key)
134 		return TEE_ERROR_BAD_PARAMETERS;
135 
136 	memcpy(public_key.pub, key->pub, sizeof(public_key.pub));
137 
138 	if (ed25519_verify(msg, msg_len, sig, sig_len, &stat,
139 			   &public_key) != CRYPT_OK)
140 		return TEE_ERROR_BAD_PARAMETERS;
141 
142 	if (stat != 1)
143 		return TEE_ERROR_SIGNATURE_INVALID;
144 
145 	return TEE_SUCCESS;
146 }
147 
148 TEE_Result crypto_acipher_ed25519ctx_verify(struct ed25519_keypair *key,
149 					    const uint8_t *msg, size_t msg_len,
150 					    const uint8_t *sig, size_t sig_len,
151 					    bool ph_flag,
152 					    const uint8_t *ctx, size_t ctxlen)
153 {
154 	int stat = 0;
155 	curve25519_key public_key = {
156 		.type = PK_PUBLIC,
157 		.algo = LTC_OID_ED25519,
158 	};
159 
160 	if (!key)
161 		return TEE_ERROR_BAD_PARAMETERS;
162 
163 	memcpy(public_key.pub, key->pub, sizeof(public_key.pub));
164 
165 	if (ph_flag) {
166 		if (ed25519ph_verify(msg, msg_len, sig, sig_len, ctx, ctxlen,
167 				     &stat, &public_key) != CRYPT_OK)
168 			return TEE_ERROR_BAD_PARAMETERS;
169 	} else {
170 		if (ed25519ctx_verify(msg, msg_len, sig, sig_len, ctx, ctxlen,
171 				      &stat, &public_key) != CRYPT_OK)
172 			return TEE_ERROR_BAD_PARAMETERS;
173 	}
174 
175 	if (stat != 1)
176 		return TEE_ERROR_SIGNATURE_INVALID;
177 
178 	return TEE_SUCCESS;
179 }
180