• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #define HUKS_DISABLE_LOG_AT_FILE_TO_REDUCE_ROM_SIZE
16 
17 #ifdef HKS_CONFIG_FILE
18 #include HKS_CONFIG_FILE
19 #else
20 #include "hks_config.h"
21 #endif
22 
23 #ifdef _CUT_AUTHENTICATE_
24 #undef HKS_SUPPORT_ED25519_C
25 #endif
26 
27 #ifdef HKS_SUPPORT_ED25519_C
28 
29 #include "hks_crypto_ed25519.h"
30 
31 
32 #include "hks_crypto_hal.h"
33 #include "hks_log.h"
34 #include "hks_mem.h"
35 #include "hks_template.h"
36 
37 #include <crypto/ecx.h>
38 #include <securec.h>
39 
40 #define CRYPTO_SUCCESS 1
41 #define ED25519_PRIVATE_KEY_LEN 32
42 #define ED25519_PUBLIC_KEY_LEN 32
43 
44 #ifdef HKS_SUPPORT_ED25519_GENERATE_KEY
SaveEd25519KeyMaterial(const struct HksBlob * pubKey,const struct HksBlob * priKey,struct HksBlob * keyOut)45 static int32_t SaveEd25519KeyMaterial(const struct HksBlob *pubKey, const struct HksBlob *priKey,
46     struct HksBlob *keyOut)
47 {
48     uint32_t totalSize = sizeof(struct KeyMaterial25519) + pubKey->size + priKey->size;
49     uint8_t *buffer = (uint8_t *)HksMalloc(totalSize);
50     HKS_IF_NULL_RETURN(buffer, HKS_ERROR_MALLOC_FAIL)
51 
52     struct KeyMaterial25519 *keyMaterial = (struct KeyMaterial25519 *)buffer;
53     keyMaterial->keyAlg = HKS_ALG_ED25519;
54     keyMaterial->keySize = HKS_CURVE25519_KEY_SIZE_256;
55     keyMaterial->pubKeySize = pubKey->size;
56     keyMaterial->priKeySize = priKey->size;
57     keyMaterial->reserved = 0;
58 
59     uint32_t offset = sizeof(struct KeyMaterial25519);
60     if (memcpy_s(buffer + offset, totalSize - offset, pubKey->data, pubKey->size) != EOK) {
61         HKS_LOG_E("copy ed25519 public key failed");
62         (void)memset_s(buffer, totalSize, 0, totalSize);
63         HKS_FREE(buffer);
64         return HKS_ERROR_INSUFFICIENT_MEMORY;
65     }
66 
67     offset += pubKey->size;
68     if (memcpy_s(buffer + offset, totalSize - offset, priKey->data, priKey->size) != EOK) {
69         HKS_LOG_E("copy ed25519 private key failed");
70         (void)memset_s(buffer, totalSize, 0, totalSize);
71         HKS_FREE(buffer);
72         return HKS_ERROR_INSUFFICIENT_MEMORY;
73     }
74 
75     keyOut->data = buffer;
76     keyOut->size = totalSize;
77     return HKS_SUCCESS;
78 }
79 
IsBlobZero(const struct HksBlob * key)80 static bool IsBlobZero(const struct HksBlob *key)
81 {
82     for (uint32_t i = 0; i < key->size; ++i) {
83         if (key->data[i] != 0) {
84             return false;
85         }
86     }
87     return true;
88 }
89 
HksEd25519GenerateKey(const struct HksKeySpec * spec,struct HksBlob * keyOut)90 int32_t HksEd25519GenerateKey(const struct HksKeySpec *spec, struct HksBlob *keyOut)
91 {
92     (void)spec;
93     uint8_t pubKey[ED25519_PUBLIC_KEY_LEN] = {0};
94     uint8_t priKey[ED25519_PRIVATE_KEY_LEN] = {0};
95     struct HksBlob pubKeyBlob = { ED25519_PUBLIC_KEY_LEN, pubKey };
96     struct HksBlob priKeyBlob = { ED25519_PRIVATE_KEY_LEN, priKey };
97 
98     struct HksBlob tmp = { ED25519_PUBLIC_KEY_LEN, priKeyBlob.data };
99     int32_t ret = HksCryptoHalFillPrivRandom(&tmp);
100     HKS_IF_NOT_SUCC_RETURN(ret, ret)
101 
102     ossl_ed25519_public_from_private(NULL, pubKeyBlob.data, priKeyBlob.data, NULL);
103     if (IsBlobZero(&pubKeyBlob) || IsBlobZero(&priKeyBlob)) {
104         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
105     }
106 
107     ret = SaveEd25519KeyMaterial(&pubKeyBlob, &priKeyBlob, keyOut);
108     (void)memset_s(priKeyBlob.data, ED25519_PRIVATE_KEY_LEN, 0, ED25519_PRIVATE_KEY_LEN);
109     return ret;
110 }
111 #endif /* HKS_SUPPORT_ED25519_GENERATE_KEY */
112 
CheckEd25519Material(const struct HksBlob * key)113 static int32_t CheckEd25519Material(const struct HksBlob *key)
114 {
115     uint32_t totalSize = sizeof(struct KeyMaterial25519);
116     if (key->size < totalSize) {
117         HKS_LOG_E("Ed25519 key material too small");
118         return HKS_ERROR_INVALID_KEY_INFO;
119     }
120 
121     struct KeyMaterial25519 *km = (struct KeyMaterial25519 *)key->data;
122     if (((key->size - totalSize) < km->pubKeySize) ||
123         ((key->size - totalSize) < km->priKeySize) ||
124         (km->pubKeySize > (UINT32_MAX - km->priKeySize)) ||
125         ((key->size - totalSize) < (km->pubKeySize + km->priKeySize))) {
126         HKS_LOG_E("Ed25519 key material wrong pub and pri key size %" LOG_PUBLIC "u, %" LOG_PUBLIC "u, "
127             "%" LOG_PUBLIC "u", key->size, km->pubKeySize, km->priKeySize);
128         return HKS_ERROR_INVALID_KEY_INFO;
129     }
130 
131     return HKS_SUCCESS;
132 }
133 
134 #ifdef HKS_SUPPORT_ED2519_GET_PUBLIC_KEY
GetEd25519PubKeyCheck(const struct HksBlob * key,const struct HksBlob * keyOut)135 static int32_t GetEd25519PubKeyCheck(const struct HksBlob *key, const struct HksBlob *keyOut)
136 {
137     int32_t ret = CheckEd25519Material(key);
138     HKS_IF_NOT_SUCC_RETURN(ret, ret)
139 
140     /* check keyOut */
141     struct KeyMaterial25519 *km = (struct KeyMaterial25519 *)key->data;
142     if ((km->pubKeySize > (UINT32_MAX - sizeof(struct KeyMaterial25519))) ||
143         (keyOut->size < (sizeof(struct KeyMaterial25519) + km->pubKeySize))) {
144         HKS_LOG_E("Ecc public keyOut size too small! keyOut size = 0x%" LOG_PUBLIC "X", keyOut->size);
145         return HKS_ERROR_BUFFER_TOO_SMALL;
146     }
147 
148     return HKS_SUCCESS;
149 }
150 
HksGetEd25519PubKey(const struct HksBlob * input,struct HksBlob * output)151 int32_t HksGetEd25519PubKey(const struct HksBlob *input, struct HksBlob *output)
152 {
153     int32_t ret = GetEd25519PubKeyCheck(input, output);
154     HKS_IF_NOT_SUCC_RETURN(ret, ret)
155 
156     struct KeyMaterial25519 *key = (struct KeyMaterial25519 *)input->data;
157     uint32_t outLen = sizeof(struct KeyMaterial25519) + key->pubKeySize;
158     if (memcpy_s(output->data, output->size, key, outLen) != EOK) {
159         HKS_LOG_E("memcpy_s ed25519 pub key failed");
160         return HKS_ERROR_INSUFFICIENT_MEMORY;
161     }
162 
163     ((struct KeyMaterial25519 *)output->data)->priKeySize = 0;
164     output->size = outLen;
165     return HKS_SUCCESS;
166 }
167 #endif
168 
169 #ifdef HKS_SUPPORT_ED25519_SIGN_VERIFY
HksEd25519Sign(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,struct HksBlob * signature)170 int32_t HksEd25519Sign(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
171     const struct HksBlob *message, struct HksBlob *signature)
172 {
173     (void)usageSpec;
174     int32_t ret = CheckEd25519Material(key);
175     HKS_IF_NOT_SUCC_RETURN(ret, ret)
176     if (signature->size < HKS_SIGNATURE_MIN_SIZE ||
177         key->size <= (sizeof(struct KeyMaterial25519) + ED25519_PUBLIC_KEY_LEN)) {
178         HKS_LOG_E("invalid param : signature size = %" LOG_PUBLIC "u, key size = %" LOG_PUBLIC "u",
179             signature->size, key->size);
180         return HKS_ERROR_INVALID_ARGUMENT;
181     }
182 
183     ret = ossl_ed25519_sign(signature->data, message->data, message->size,
184         key->data + sizeof(struct KeyMaterial25519),
185         key->data + sizeof(struct KeyMaterial25519) + ED25519_PUBLIC_KEY_LEN, NULL, NULL);
186     if (ret != CRYPTO_SUCCESS) {
187         HKS_LOG_E("ED25519_sign failed");
188         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
189     }
190     signature->size = HKS_SIGNATURE_MIN_SIZE;
191 
192     return HKS_SUCCESS;
193 }
194 
HksEd25519Verify(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const struct HksBlob * message,const struct HksBlob * signature)195 int32_t HksEd25519Verify(const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
196     const struct HksBlob *message, const struct HksBlob *signature)
197 {
198     (void)usageSpec;
199     int32_t ret = CheckEd25519Material(key);
200     HKS_IF_NOT_SUCC_RETURN(ret, ret)
201     if (signature->size < HKS_SIGNATURE_MIN_SIZE) {
202         return HKS_ERROR_INVALID_ARGUMENT;
203     }
204 
205     ret = ossl_ed25519_verify(message->data, message->size, signature->data,
206         key->data + sizeof(struct KeyMaterial25519), NULL, NULL);
207     if (ret != CRYPTO_SUCCESS) {
208         HKS_LOG_E("ED25519_verify failed");
209         return HKS_ERROR_CRYPTO_ENGINE_ERROR;
210     }
211 
212     return HKS_SUCCESS;
213 }
214 #endif /* HKS_SUPPORT_ED25519_SIGN_VERIFY */
215 #endif /* HKS_SUPPORT_ED25519_C */
216