1 /* 2 * Copyright (C) 2022-2023 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 16 #include "mbedtls_ec_adapter.h" 17 18 #include <mbedtls/base64.h> 19 #include <mbedtls/bignum.h> 20 #include <mbedtls/ctr_drbg.h> 21 #include <mbedtls/entropy.h> 22 #include <mbedtls/error.h> 23 #include <mbedtls/pk.h> 24 #include <mbedtls/x509.h> 25 26 #include "hal_error.h" 27 #include "hc_log.h" 28 #include "huks_adapter.h" 29 30 #define LOG_AND_RETURN_IF_MBED_FAIL(ret, fmt, ...) \ 31 do { \ 32 if ((ret) != 0) { \ 33 LOGE(fmt, ##__VA_ARGS__); \ 34 return HAL_ERR_MBEDTLS; \ 35 } \ 36 } while (0) 37 38 #define LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, fmt, ...) \ 39 do { \ 40 if ((ret) != 0) { \ 41 LOGE(fmt, ##__VA_ARGS__); \ 42 goto CLEAN_UP; \ 43 } \ 44 } while (0) 45 46 #define LEN_HALF_DIVISOR 2 47 #define BITS_PER_BYTE 8 48 #define EC_LEN 64 49 #define SHA256_HASH_LEN 32 50 #define P256_KEY_SIZE 32 51 #define P256_PUBLIC_SIZE 64 // P256_KEY_SIZE * 2 52 #define PARAM_A_INDEX 2 53 #define PARAM_U_INDEX 4 54 #define PARAM_MINUS_A_INDEX 3 55 #define PARAM_ONE_INDEX 5 56 #define HASH_TO_POINT_PARA_NUMS 6 57 58 typedef struct Blob { 59 uint32_t dataSize; 60 uint8_t *data; 61 } Blob; 62 63 static const uint8_t POINT_A[] = { 64 0x04, 0x53, 0xf9, 0xe4, 0xf4, 0xbc, 0x3a, 0xb5, 0x9d, 0x44, 0x78, 0x45, 0x21, 0x13, 0x8b, 0x49, 65 0xba, 0xa3, 0x1c, 0xe2, 0xa8, 0xdb, 0xbd, 0xb8, 0xd6, 0x73, 0x31, 0x46, 0x3a, 0x69, 0x53, 0xf1, 66 0xed, 0xef, 0x96, 0x1e, 0xdb, 0x42, 0xbe, 0x3a, 0x24, 0x43, 0xc4, 0x08, 0x23, 0xfb, 0x58, 0xee, 67 0x61, 0x24, 0x8b, 0x59, 0x64, 0x65, 0x2d, 0xbc, 0x6b, 0xa5, 0x1d, 0x6e, 0x04, 0x22, 0x53, 0xae, 68 0x27 69 }; 70 static const uint8_t POINT_B[] = { 71 0x04, 0x03, 0x4d, 0x11, 0x11, 0xa6, 0x3f, 0x5f, 0x72, 0x43, 0x59, 0x73, 0x8b, 0x46, 0xc3, 0xfd, 72 0x70, 0x58, 0xb0, 0xb6, 0x11, 0xd3, 0x4f, 0xf3, 0x49, 0xa0, 0xd2, 0x86, 0xd7, 0x35, 0x33, 0xc5, 73 0x36, 0xe4, 0x99, 0xcc, 0x13, 0x47, 0xe4, 0xab, 0xde, 0x8f, 0x3a, 0xd6, 0x65, 0x1a, 0x77, 0x0b, 74 0xc4, 0x82, 0xd5, 0xac, 0x4b, 0x5d, 0xe4, 0xcc, 0x48, 0xb0, 0x54, 0x6c, 0x9b, 0x76, 0x76, 0x1a, 75 0xba 76 }; 77 78 static uint8_t g_hash2pointParas[HASH_TO_POINT_PARA_NUMS][BYTE_LENGTH_CURVE_25519] = { 79 { 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0:p */ 80 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 81 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 82 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed }, 83 { 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 1:divide_minus_p_1_2 */ 84 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 85 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 86 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6 }, 87 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 2:A */ 88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 90 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x6d, 0x06 }, 91 { 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 3:-A */ 92 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 93 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 94 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x92, 0xe7 }, 95 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4:u = 2 */ 96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }, 99 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5:1 */ 100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, 103 }; 104 105 static const uint8_t RANDOM_SEED_CUSTOM[] = { 0x4C, 0x54, 0x4B, 0x53 }; // LTKS means LiteKeystore 106 IsValidBlob(const Blob * blob)107 static bool IsValidBlob(const Blob *blob) 108 { 109 return (blob != NULL) && (blob->data != NULL) && (blob->dataSize != 0); 110 } 111 IsValidUint8Buff(const Uint8Buff * buff)112 static bool IsValidUint8Buff(const Uint8Buff *buff) 113 { 114 return (buff != NULL) && (buff->val != NULL) && (buff->length != 0); 115 } 116 InitPointParams(mbedtls_mpi * scalarA,mbedtls_mpi * scalarB,mbedtls_ecp_point * pointA,mbedtls_ecp_point * pointB,mbedtls_ecp_point * result)117 static void InitPointParams(mbedtls_mpi *scalarA, mbedtls_mpi *scalarB, mbedtls_ecp_point *pointA, 118 mbedtls_ecp_point *pointB, mbedtls_ecp_point *result) 119 { 120 mbedtls_mpi_init(scalarA); 121 mbedtls_mpi_init(scalarB); 122 mbedtls_ecp_point_init(pointA); 123 mbedtls_ecp_point_init(pointB); 124 mbedtls_ecp_point_init(result); 125 } 126 FreePointParams(mbedtls_mpi * scalarA,mbedtls_mpi * scalarB,mbedtls_ecp_point * pointA,mbedtls_ecp_point * pointB,mbedtls_ecp_point * result)127 static void FreePointParams(mbedtls_mpi *scalarA, mbedtls_mpi *scalarB, mbedtls_ecp_point *pointA, 128 mbedtls_ecp_point *pointB, mbedtls_ecp_point *result) 129 { 130 mbedtls_mpi_free(scalarA); 131 mbedtls_mpi_free(scalarB); 132 mbedtls_ecp_point_free(pointA); 133 mbedtls_ecp_point_free(pointB); 134 mbedtls_ecp_point_free(result); 135 } 136 SwapEndian(uint8_t * pubKey,int len)137 static void SwapEndian(uint8_t *pubKey, int len) 138 { 139 if ((pubKey == NULL) || (len <= 0)) { 140 return; 141 } 142 for (int i = 0; i < len / LEN_HALF_DIVISOR; ++i) { 143 uint8_t tmp = pubKey[i]; 144 pubKey[i] = pubKey[len - i - 1]; 145 pubKey[len - i - 1] = tmp; 146 } 147 } 148 FreeCleanFiveBns(mbedtls_mpi * bn1,mbedtls_mpi * bn2,mbedtls_mpi * bn3,mbedtls_mpi * bn4,mbedtls_mpi * bn5)149 static void FreeCleanFiveBns(mbedtls_mpi *bn1, mbedtls_mpi *bn2, mbedtls_mpi *bn3, 150 mbedtls_mpi *bn4, mbedtls_mpi *bn5) 151 { 152 mbedtls_mpi_free(bn1); 153 mbedtls_mpi_free(bn2); 154 mbedtls_mpi_free(bn3); 155 mbedtls_mpi_free(bn4); 156 mbedtls_mpi_free(bn5); 157 } 158 CalTmpParaX(mbedtls_mpi * tmpY,const mbedtls_mpi * tmpX,const mbedtls_mpi * modP)159 static int32_t CalTmpParaX(mbedtls_mpi *tmpY, const mbedtls_mpi *tmpX, const mbedtls_mpi *modP) 160 { 161 int32_t status; 162 mbedtls_mpi tmpBnA; 163 mbedtls_mpi tmpBnB; 164 mbedtls_mpi tmpBnC; 165 mbedtls_mpi tmpBnE; 166 mbedtls_mpi paraBnA; 167 mbedtls_mpi paraBnU; 168 169 mbedtls_mpi_init(&tmpBnA); 170 mbedtls_mpi_init(&tmpBnB); 171 mbedtls_mpi_init(&tmpBnC); 172 mbedtls_mpi_init(&tmpBnE); 173 mbedtls_mpi_init(¶BnA); 174 mbedtls_mpi_init(¶BnU); 175 176 status = mbedtls_mpi_read_binary(¶BnA, g_hash2pointParas[PARAM_A_INDEX], BYTE_LENGTH_CURVE_25519); 177 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error1"); 178 179 status = mbedtls_mpi_read_binary(¶BnU, g_hash2pointParas[PARAM_U_INDEX], BYTE_LENGTH_CURVE_25519); 180 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error2"); 181 182 status = mbedtls_mpi_copy(&tmpBnB, tmpX); 183 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error3"); 184 /* a := b ^ 3 + A * b ^ 2 + b */ 185 186 status = mbedtls_mpi_exp_mod(&tmpBnE, &tmpBnB, ¶BnU, modP, NULL); 187 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error4"); // b^2 188 189 status = mbedtls_mpi_mul_mpi(&tmpBnC, &tmpBnE, &tmpBnB); 190 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error5"); 191 status = mbedtls_mpi_mod_mpi(&tmpBnC, &tmpBnC, modP); 192 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error6"); // b^3 193 194 status = mbedtls_mpi_mul_mpi(&tmpBnA, &tmpBnE, ¶BnA); // A*b^2 195 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error7"); 196 status = mbedtls_mpi_mod_mpi(&tmpBnA, &tmpBnA, modP); 197 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error8"); 198 199 status = mbedtls_mpi_add_mpi(&tmpBnE, &tmpBnC, &tmpBnA); // b^3 + A*b^2 200 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error9"); 201 status = mbedtls_mpi_mod_mpi(&tmpBnE, &tmpBnE, modP); 202 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error10"); 203 204 status = mbedtls_mpi_add_mpi(tmpY, &tmpBnE, &tmpBnB); // b^3 + A*b^2 + b 205 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error11"); 206 status = mbedtls_mpi_mod_mpi(tmpY, tmpY, modP); 207 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParaX error12"); 208 209 CLEAN_UP: 210 FreeCleanFiveBns(¶BnA, &tmpBnA, &tmpBnB, &tmpBnC, &tmpBnE); 211 mbedtls_mpi_free(¶BnU); 212 return status; 213 } 214 CalTmpParab(mbedtls_mpi * tmpX,const mbedtls_mpi * modP,const uint8_t * hash,uint32_t hashLen)215 static int32_t CalTmpParab(mbedtls_mpi *tmpX, const mbedtls_mpi *modP, const uint8_t *hash, uint32_t hashLen) 216 { 217 int32_t status; 218 mbedtls_mpi paraBnNegA; 219 mbedtls_mpi paraBNOne; 220 mbedtls_mpi paraBnU; 221 mbedtls_mpi tmpBnA; 222 mbedtls_mpi tmpBnB; 223 224 mbedtls_mpi_init(¶BnNegA); 225 mbedtls_mpi_init(¶BNOne); 226 mbedtls_mpi_init(¶BnU); 227 mbedtls_mpi_init(&tmpBnA); 228 mbedtls_mpi_init(&tmpBnB); 229 230 status = mbedtls_mpi_read_binary(¶BnNegA, g_hash2pointParas[PARAM_MINUS_A_INDEX], BYTE_LENGTH_CURVE_25519); 231 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error1"); 232 status = mbedtls_mpi_read_binary(¶BNOne, g_hash2pointParas[PARAM_ONE_INDEX], BYTE_LENGTH_CURVE_25519); 233 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error2"); 234 status = mbedtls_mpi_read_binary(¶BnU, g_hash2pointParas[PARAM_U_INDEX], BYTE_LENGTH_CURVE_25519); 235 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error3"); 236 status = mbedtls_mpi_read_binary(&tmpBnA, hash, hashLen); 237 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error4"); 238 239 /* b := -A / (1 + u * a ^ 2) */ 240 status = mbedtls_mpi_exp_mod(&tmpBnB, &tmpBnA, ¶BnU, modP, NULL); 241 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error5"); 242 243 status = mbedtls_mpi_mul_mpi(&tmpBnA, &tmpBnB, ¶BnU); 244 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error6"); 245 status = mbedtls_mpi_mod_mpi(&tmpBnA, &tmpBnA, modP); 246 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error7"); 247 248 status = mbedtls_mpi_add_mpi(&tmpBnB, &tmpBnA, ¶BNOne); 249 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error8"); 250 status = mbedtls_mpi_mod_mpi(&tmpBnB, &tmpBnB, modP); 251 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error9"); 252 253 status = mbedtls_mpi_inv_mod(&tmpBnA, &tmpBnB, modP); 254 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error10"); 255 256 status = mbedtls_mpi_mul_mpi(tmpX, &tmpBnA, ¶BnNegA); 257 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error11"); 258 status = mbedtls_mpi_mod_mpi(tmpX, tmpX, modP); 259 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "CalTmpParab error12"); 260 CLEAN_UP: 261 FreeCleanFiveBns(¶BnNegA, ¶BNOne, ¶BnU, &tmpBnA, &tmpBnB); 262 return status; 263 } 264 265 /* 266 * hash2point function, use BoringSSL big number algorithm library; 267 * p_point(little endian): the output pointer of Curve25519 point; 268 * p_hash (little endian): the input pointer of string; 269 */ Elligator(unsigned char * point,int pointLength,const unsigned char * hash,int hashLength)270 static int32_t Elligator(unsigned char *point, int pointLength, const unsigned char *hash, int hashLength) 271 { 272 mbedtls_mpi paraBnP; 273 mbedtls_mpi paraBnSquare; 274 mbedtls_mpi paraBnNegA; 275 mbedtls_mpi tmpBnA; 276 mbedtls_mpi tmpBnB; 277 mbedtls_mpi tmpBnC; 278 mbedtls_mpi tmpBnE; 279 280 mbedtls_mpi_init(¶BnP); 281 mbedtls_mpi_init(¶BnSquare); 282 mbedtls_mpi_init(¶BnNegA); 283 mbedtls_mpi_init(&tmpBnA); 284 mbedtls_mpi_init(&tmpBnB); 285 mbedtls_mpi_init(&tmpBnC); 286 mbedtls_mpi_init(&tmpBnE); 287 288 int32_t status = mbedtls_mpi_read_binary(¶BnP, g_hash2pointParas[0], BYTE_LENGTH_CURVE_25519); 289 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error1"); 290 status = mbedtls_mpi_read_binary(¶BnSquare, g_hash2pointParas[1], BYTE_LENGTH_CURVE_25519); 291 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error2"); 292 status = mbedtls_mpi_read_binary(¶BnNegA, g_hash2pointParas[PARAM_MINUS_A_INDEX], BYTE_LENGTH_CURVE_25519); 293 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error3"); 294 295 status = CalTmpParab(&tmpBnB, ¶BnP, hash, hashLength); 296 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error4"); 297 status = CalTmpParaX(&tmpBnA, &tmpBnB, ¶BnP); 298 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error5"); 299 300 status = mbedtls_mpi_sub_mpi(&tmpBnC, ¶BnP, &tmpBnB); 301 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error6"); 302 status = mbedtls_mpi_mod_mpi(&tmpBnC, &tmpBnC, ¶BnP); 303 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error7"); 304 305 status = mbedtls_mpi_add_mpi(&tmpBnC, &tmpBnC, ¶BnNegA); 306 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error8"); 307 status = mbedtls_mpi_mod_mpi(&tmpBnC, &tmpBnC, ¶BnP); 308 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error9"); 309 310 status = mbedtls_mpi_exp_mod(&tmpBnE, &tmpBnA, ¶BnSquare, ¶BnP, NULL); 311 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error10"); 312 313 status = mbedtls_mpi_safe_cond_swap(&tmpBnB, &tmpBnC, (mbedtls_mpi_cmp_mpi(¶BnSquare, &tmpBnE) == 1)); 314 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error11"); 315 316 status = mbedtls_mpi_write_binary(&tmpBnC, point, pointLength); 317 LOG_AND_GOTO_CLEANUP_IF_FAIL(status, "Elligator error12"); 318 319 SwapEndian(point, pointLength); 320 CLEAN_UP: 321 mbedtls_mpi_free(¶BnP); 322 mbedtls_mpi_free(¶BnSquare); 323 FreeCleanFiveBns(¶BnNegA, &tmpBnA, &tmpBnB, &tmpBnC, &tmpBnE); 324 return status; 325 } 326 CalculateMessageDigest(mbedtls_md_type_t type,const Blob * input,Blob * output)327 static int32_t CalculateMessageDigest(mbedtls_md_type_t type, const Blob *input, Blob *output) 328 { 329 const mbedtls_md_info_t *info = mbedtls_md_info_from_type(type); 330 if (info == NULL) { 331 return HAL_ERR_NOT_SUPPORTED; 332 } 333 334 uint32_t outSize = mbedtls_md_get_size(info); 335 if (output->dataSize < outSize) { 336 return HAL_ERR_SHORT_BUFFER; 337 } 338 339 int32_t ret = mbedtls_md(info, input->data, input->dataSize, output->data); 340 LOG_AND_RETURN_IF_MBED_FAIL(ret, "Calculate message digest failed.\n"); 341 342 output->dataSize = outSize; 343 return HAL_SUCCESS; 344 } 345 Sha256(const Blob * input,Blob * output)346 static int32_t Sha256(const Blob *input, Blob *output) 347 { 348 if (!IsValidBlob(input) || !IsValidBlob(output)) { 349 LOGE("Input params for sha256 is invalid."); 350 return HAL_ERR_INVALID_PARAM; 351 } 352 return CalculateMessageDigest(MBEDTLS_MD_SHA256, input, output); 353 } 354 ReadBigNums(mbedtls_mpi * x,mbedtls_mpi * y,const Blob * blob)355 static int32_t ReadBigNums(mbedtls_mpi *x, mbedtls_mpi *y, const Blob *blob) 356 { 357 int32_t ret = mbedtls_mpi_read_binary(x, blob->data, P256_KEY_SIZE); 358 LOG_AND_RETURN_IF_MBED_FAIL(ret, "Read x coordinate of public key failed."); 359 ret = mbedtls_mpi_read_binary(y, blob->data + P256_KEY_SIZE, P256_KEY_SIZE); 360 LOG_AND_RETURN_IF_MBED_FAIL(ret, "Read y coordinate of public key failed."); 361 return HAL_SUCCESS; 362 } 363 ReadEcPublicKey(mbedtls_ecp_point * point,const Blob * publicKey)364 static int32_t ReadEcPublicKey(mbedtls_ecp_point *point, const Blob *publicKey) 365 { 366 int32_t ret = ReadBigNums(&point->MBEDTLS_PRIVATE(X), &point->MBEDTLS_PRIVATE(Y), publicKey); 367 LOG_AND_RETURN_IF_MBED_FAIL(ret, "Read coordinate of public key failed."); 368 ret = mbedtls_mpi_lset(&point->MBEDTLS_PRIVATE(Z), 1); 369 LOG_AND_RETURN_IF_MBED_FAIL(ret, "Lset point z failed."); 370 return HAL_SUCCESS; 371 } 372 WriteOutBigNums(const mbedtls_mpi * x,const mbedtls_mpi * y,Blob * out)373 static int32_t WriteOutBigNums(const mbedtls_mpi *x, const mbedtls_mpi *y, Blob *out) 374 { 375 int32_t ret = mbedtls_mpi_write_binary(x, out->data, P256_KEY_SIZE); 376 LOG_AND_RETURN_IF_MBED_FAIL(ret, "Write x coordinate of public key failed."); 377 378 ret = mbedtls_mpi_write_binary(y, out->data + P256_KEY_SIZE, P256_KEY_SIZE); 379 LOG_AND_RETURN_IF_MBED_FAIL(ret, "Write y coordinate of public key failed."); 380 381 out->dataSize = P256_PUBLIC_SIZE; 382 return HAL_SUCCESS; 383 } 384 WriteOutEcPublicKey(const mbedtls_ecp_point * point,Blob * publicKey)385 static int32_t WriteOutEcPublicKey(const mbedtls_ecp_point *point, Blob *publicKey) 386 { 387 return WriteOutBigNums(&point->MBEDTLS_PRIVATE(X), &point->MBEDTLS_PRIVATE(Y), publicKey); 388 } 389 EcKeyAgreementLog(mbedtls_ecp_keypair * keyPair,mbedtls_ecp_point * p,mbedtls_ctr_drbg_context * ctrDrbg)390 static int EcKeyAgreementLog(mbedtls_ecp_keypair *keyPair, mbedtls_ecp_point *p, mbedtls_ctr_drbg_context *ctrDrbg) 391 { 392 return mbedtls_ecp_mul_restartable(&keyPair->MBEDTLS_PRIVATE(grp), p, &keyPair->MBEDTLS_PRIVATE(d), 393 &keyPair->MBEDTLS_PRIVATE(Q), mbedtls_ctr_drbg_random, ctrDrbg, NULL); 394 } 395 EcKeyAgreement(const Blob * privateKey,const Blob * publicKey,Blob * secretKey)396 static int32_t EcKeyAgreement(const Blob *privateKey, const Blob *publicKey, Blob *secretKey) 397 { 398 if (!IsValidBlob(publicKey) || publicKey->dataSize != P256_PUBLIC_SIZE || !IsValidBlob(secretKey) || 399 secretKey->dataSize != P256_PUBLIC_SIZE || !IsValidBlob(privateKey)) { 400 LOGE("Input params for ec key agree is invalid."); 401 return HAL_ERR_INVALID_PARAM; 402 } 403 mbedtls_mpi *secret = HcMalloc(sizeof(mbedtls_mpi), 0); 404 mbedtls_ecp_keypair *keyPair = HcMalloc(sizeof(mbedtls_ecp_keypair), 0); 405 mbedtls_entropy_context *entropy = HcMalloc(sizeof(mbedtls_entropy_context), 0); 406 mbedtls_ctr_drbg_context *ctrDrbg = HcMalloc(sizeof(mbedtls_ctr_drbg_context), 0); 407 if ((secret == NULL) || (keyPair == NULL) || (entropy == NULL) || (ctrDrbg == NULL)) { 408 LOGE("Malloc for mbedtls ec key param failed."); 409 HcFree(secret); 410 HcFree(keyPair); 411 HcFree(entropy); 412 HcFree(ctrDrbg); 413 return HAL_ERR_BAD_ALLOC; 414 } 415 mbedtls_mpi_init(secret); 416 mbedtls_ecp_keypair_init(keyPair); 417 mbedtls_entropy_init(entropy); 418 mbedtls_ctr_drbg_init(ctrDrbg); 419 mbedtls_ecp_point p; 420 mbedtls_ecp_point_init(&p); 421 int32_t ret = ReadEcPublicKey(&keyPair->MBEDTLS_PRIVATE(Q), publicKey); 422 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read the public key failed.\n"); 423 ret = mbedtls_ecp_group_load(&keyPair->MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1); 424 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Load the ecp group failed.\n"); 425 ret = mbedtls_mpi_read_binary(&keyPair->MBEDTLS_PRIVATE(d), privateKey->data, privateKey->dataSize); 426 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read the private key failed.\n"); 427 ret = mbedtls_ctr_drbg_seed(ctrDrbg, mbedtls_entropy_func, entropy, 428 RANDOM_SEED_CUSTOM, sizeof(RANDOM_SEED_CUSTOM)); 429 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set custom string failed.\n"); 430 LOG_AND_GOTO_CLEANUP_IF_FAIL(EcKeyAgreementLog(keyPair, &p, ctrDrbg), "Compute secret key failed.\n"); 431 LOG_AND_GOTO_CLEANUP_IF_FAIL(mbedtls_mpi_copy(secret, &p.MBEDTLS_PRIVATE(X)), "Copy secret failed.\n"); 432 LOG_AND_GOTO_CLEANUP_IF_FAIL(WriteOutEcPublicKey(&p, secretKey), "Write out ec public key failed.\n"); 433 CLEAN_UP: 434 mbedtls_mpi_free(secret); 435 mbedtls_ecp_keypair_free(keyPair); 436 mbedtls_entropy_free(entropy); 437 mbedtls_ctr_drbg_free(ctrDrbg); 438 mbedtls_ecp_point_free(&p); 439 HcFree(secret); 440 HcFree(keyPair); 441 HcFree(entropy); 442 HcFree(ctrDrbg); 443 LOG_AND_RETURN_IF_MBED_FAIL(ret, "Ec key agree failed."); 444 return HAL_SUCCESS; 445 } 446 EcHashToPoint(const Blob * hash,Blob * point)447 static int32_t EcHashToPoint(const Blob *hash, Blob *point) 448 { 449 mbedtls_mpi scalarA; 450 mbedtls_mpi scalarB; 451 mbedtls_ecp_point pointA; 452 mbedtls_ecp_point pointB; 453 mbedtls_ecp_point result; 454 InitPointParams(&scalarA, &scalarB, &pointA, &pointB, &result); 455 456 mbedtls_ecp_group grp; 457 mbedtls_ecp_group_init(&grp); 458 uint8_t digest[SHA256_HASH_LEN] = { 0 }; 459 Blob digestBlob = { sizeof(digest), digest }; 460 461 int32_t ret = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1); 462 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Load ecp group failed.\n"); 463 ret = mbedtls_ecp_point_read_binary(&grp, &pointA, POINT_A, sizeof(POINT_A)); 464 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read point A failed.\n"); 465 ret = mbedtls_ecp_point_read_binary(&grp, &pointB, POINT_B, sizeof(POINT_B)); 466 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read point B failed.\n"); 467 ret = Sha256(hash, &digestBlob); 468 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Compute message digest failed.\n"); 469 ret = mbedtls_mpi_lset(&scalarA, 1); 470 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set number one failed.\n"); 471 ret = mbedtls_mpi_read_binary(&scalarB, digest, SHA256_HASH_LEN); 472 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read digest failed.\n"); 473 ret = mbedtls_ecp_muladd(&grp, &result, &scalarA, &pointA, &scalarB, &pointB); 474 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Double-scalar multiplication failed.\n"); 475 ret = mbedtls_ecp_check_pubkey(&grp, &result); 476 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Invalid point on P256 is returned.\n"); 477 ret = WriteOutEcPublicKey(&result, point); 478 LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Write out public key failed.\n"); 479 CLEAN_UP: 480 FreePointParams(&scalarA, &scalarB, &pointA, &pointB, &result); 481 mbedtls_ecp_group_free(&grp); 482 LOG_AND_RETURN_IF_MBED_FAIL(ret, "Ec hash to point failed."); 483 return HAL_SUCCESS; 484 } 485 486 // only support P256 HashToPoint for standard system MbedtlsHashToPoint(const Uint8Buff * hash,Uint8Buff * outEcPoint)487 int32_t MbedtlsHashToPoint(const Uint8Buff *hash, Uint8Buff *outEcPoint) 488 { 489 CHECK_PTR_RETURN_HAL_ERROR_CODE(hash, "hash"); 490 CHECK_PTR_RETURN_HAL_ERROR_CODE(hash->val, "hash->val"); 491 CHECK_LEN_EQUAL_RETURN(hash->length, SHA256_LEN, "hash->length"); 492 CHECK_PTR_RETURN_HAL_ERROR_CODE(outEcPoint, "outEcPoint"); 493 CHECK_PTR_RETURN_HAL_ERROR_CODE(outEcPoint->val, "outEcPoint->val"); 494 CHECK_LEN_EQUAL_RETURN(outEcPoint->length, EC_LEN, "outEcPoint->length"); 495 496 struct Blob hashBlob = { 497 .dataSize = hash->length, 498 .data = hash->val 499 }; 500 struct Blob pointBlob = { 501 .dataSize = outEcPoint->length, 502 .data = outEcPoint->val 503 }; 504 505 int32_t ret = EcHashToPoint(&hashBlob, &pointBlob); 506 if (ret != 0 || pointBlob.dataSize != EC_LEN) { 507 LOGE("HashToPoint with mbedtls for P256 failed, ret: %d", ret); 508 return HAL_FAILED; 509 } 510 511 return HAL_SUCCESS; 512 } 513 MbedtlsHashToPoint25519(const Uint8Buff * hash,Uint8Buff * outEcPoint)514 int32_t MbedtlsHashToPoint25519(const Uint8Buff *hash, Uint8Buff *outEcPoint) 515 { 516 if (!IsValidUint8Buff(hash) || !IsValidUint8Buff(outEcPoint)) { 517 return HAL_ERR_INVALID_PARAM; 518 } 519 if (hash->length != BYTE_LENGTH_CURVE_25519 || outEcPoint->length != BYTE_LENGTH_CURVE_25519) { 520 LOGE("MbedtlsHashToPoint invalid length."); 521 return HAL_ERR_INVALID_PARAM; 522 } 523 uint8_t hashTmp[BYTE_LENGTH_CURVE_25519] = { 0 }; 524 (void)memcpy_s(hashTmp, BYTE_LENGTH_CURVE_25519, hash->val, BYTE_LENGTH_CURVE_25519); 525 526 hashTmp[BYTE_LENGTH_CURVE_25519 - 1] &= ~HASH2POINT_PARA_PREPRO; 527 SwapEndian(hashTmp, BYTE_LENGTH_CURVE_25519); 528 int status = Elligator(outEcPoint->val, BYTE_LENGTH_CURVE_25519, hashTmp, BYTE_LENGTH_CURVE_25519); 529 if (status != 0) { 530 LOGE("Elligator failed, status:%d", status); 531 } 532 return status; 533 } 534 535 // only support P256 AgreeSharedSecret for standard system MbedtlsAgreeSharedSecret(const KeyBuff * priKey,const KeyBuff * pubKey,Uint8Buff * sharedKey)536 int32_t MbedtlsAgreeSharedSecret(const KeyBuff *priKey, const KeyBuff *pubKey, Uint8Buff *sharedKey) 537 { 538 CHECK_PTR_RETURN_HAL_ERROR_CODE(priKey, "priKey"); 539 CHECK_PTR_RETURN_HAL_ERROR_CODE(priKey->key, "priKey->key"); 540 CHECK_LEN_ZERO_RETURN_ERROR_CODE(priKey->keyLen, "priKey->keyLen"); 541 CHECK_PTR_RETURN_HAL_ERROR_CODE(pubKey, "devicePk"); 542 CHECK_PTR_RETURN_HAL_ERROR_CODE(pubKey->key, "devicePk->key"); 543 CHECK_LEN_ZERO_RETURN_ERROR_CODE(pubKey->keyLen, "devicePk->keyLen"); 544 CHECK_PTR_RETURN_HAL_ERROR_CODE(sharedKey, "sharedKey"); 545 CHECK_PTR_RETURN_HAL_ERROR_CODE(sharedKey->val, "sharedKey->val"); 546 CHECK_LEN_ZERO_RETURN_ERROR_CODE(sharedKey->length, "sharedKey->length"); 547 548 struct Blob priKeyBlob = { 549 .dataSize = priKey->keyLen, 550 .data = priKey->key 551 }; 552 struct Blob pubKeyBlob = { 553 .dataSize = pubKey->keyLen, 554 .data = pubKey->key 555 }; 556 struct Blob sharedKeyBlob = { 557 .dataSize = sharedKey->length, 558 .data = sharedKey->val 559 }; 560 int32_t ret = EcKeyAgreement(&priKeyBlob, &pubKeyBlob, &sharedKeyBlob); 561 if (ret != 0) { 562 LOGE("Agree key failed, ret = %d", ret); 563 return HAL_FAILED; 564 } 565 return HAL_SUCCESS; 566 } 567 MbedtlsBase64Encode(const uint8_t * byte,uint32_t byteLen,char * base64Str,uint32_t strLen,uint32_t * outLen)568 int32_t MbedtlsBase64Encode(const uint8_t *byte, uint32_t byteLen, char *base64Str, uint32_t strLen, uint32_t *outLen) 569 { 570 CHECK_PTR_RETURN_HAL_ERROR_CODE(byte, "byte"); 571 CHECK_LEN_ZERO_RETURN_ERROR_CODE(byteLen, "byteLen"); 572 CHECK_PTR_RETURN_HAL_ERROR_CODE(base64Str, "base64Str"); 573 CHECK_LEN_ZERO_RETURN_ERROR_CODE(strLen, "strLen"); 574 CHECK_PTR_RETURN_HAL_ERROR_CODE(outLen, "outLen"); 575 576 size_t needBuffLen = 0; 577 (void)mbedtls_base64_encode(NULL, 0, &needBuffLen, byte, byteLen); 578 if (needBuffLen > strLen) { 579 LOGE("The content to be written is larger than the input buffer size. Need: %zd, Buffer: %u", 580 needBuffLen, strLen); 581 return HAL_ERR_SHORT_BUFFER; 582 } 583 584 int res = mbedtls_base64_encode((unsigned char *)base64Str, strLen, &needBuffLen, byte, byteLen); 585 if (res != 0) { 586 LOGE("call mbedtls's mbedtls_base64_encode fail. res: %d", res); 587 return HAL_ERR_MBEDTLS; 588 } 589 590 *outLen = needBuffLen; 591 return HAL_SUCCESS; 592 } 593 MbedtlsBase64Decode(const char * base64Str,uint32_t strLen,uint8_t * byte,uint32_t byteLen,uint32_t * outLen)594 int32_t MbedtlsBase64Decode(const char *base64Str, uint32_t strLen, uint8_t *byte, uint32_t byteLen, uint32_t *outLen) 595 { 596 CHECK_PTR_RETURN_HAL_ERROR_CODE(base64Str, "base64Str"); 597 CHECK_LEN_ZERO_RETURN_ERROR_CODE(strLen, "strLen"); 598 CHECK_PTR_RETURN_HAL_ERROR_CODE(byte, "byte"); 599 CHECK_LEN_ZERO_RETURN_ERROR_CODE(byteLen, "byteLen"); 600 CHECK_PTR_RETURN_HAL_ERROR_CODE(outLen, "outLen"); 601 602 size_t needBuffLen = 0; 603 int res = mbedtls_base64_decode(NULL, 0, &needBuffLen, (const unsigned char *)base64Str, strLen); 604 if (res == MBEDTLS_ERR_BASE64_INVALID_CHARACTER) { 605 LOGE("The input string is not in base64 encoding format."); 606 return HAL_ERR_BASE64_FORMAT; 607 } 608 609 if (needBuffLen > byteLen) { 610 LOGE("The content to be written is larger than the input buffer size. Need: %zd, Buffer: %u", 611 needBuffLen, byteLen); 612 return HAL_ERR_SHORT_BUFFER; 613 } 614 615 res = mbedtls_base64_decode(byte, byteLen, &needBuffLen, (const unsigned char *)base64Str, strLen); 616 if (res != 0) { 617 LOGE("call mbedtls's mbedtls_base64_decode fail. res: %d", res); 618 return HAL_ERR_MBEDTLS; 619 } 620 621 *outLen = (uint32_t)needBuffLen; 622 return HAL_SUCCESS; 623 } 624