1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2022, Technology Innovation Institute (TII) 4 */ 5 6 #include <crypto/crypto.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <string_ext.h> 10 #include <tee_api_types.h> 11 #include <trace.h> 12 #include <utee_defines.h> 13 14 #include "acipher_helpers.h" 15 16 /* X25519 key is an octet string of 32 bytes */ 17 #define X25519_KEY_SIZE_BYTES UL(32) 18 19 TEE_Result crypto_acipher_alloc_x25519_keypair(struct montgomery_keypair *key, 20 size_t key_size) 21 { 22 size_t key_size_bytes = key_size / 8; 23 24 if (!key) 25 return TEE_ERROR_BAD_PARAMETERS; 26 27 memset(key, 0, sizeof(*key)); 28 29 if (key_size_bytes != X25519_KEY_SIZE_BYTES) 30 return TEE_ERROR_BAD_PARAMETERS; 31 32 key->priv = calloc(1, key_size_bytes); 33 key->pub = calloc(1, key_size_bytes); 34 35 if (!key->priv || !key->pub) { 36 free(key->priv); 37 free(key->pub); 38 return TEE_ERROR_OUT_OF_MEMORY; 39 } 40 41 return TEE_SUCCESS; 42 } 43 44 TEE_Result crypto_acipher_gen_x25519_key(struct montgomery_keypair *key, 45 size_t key_size) 46 { 47 curve25519_key ltc_tmp_key = { }; 48 size_t key_size_bytes = key_size / 8; 49 50 if (key_size_bytes != X25519_KEY_SIZE_BYTES) 51 return TEE_ERROR_BAD_PARAMETERS; 52 53 if (x25519_make_key(NULL, find_prng("prng_crypto"), <c_tmp_key) != 54 CRYPT_OK) 55 return TEE_ERROR_BAD_PARAMETERS; 56 57 if (key_size_bytes < sizeof(ltc_tmp_key.pub) || 58 key_size_bytes < sizeof(ltc_tmp_key.priv)) 59 return TEE_ERROR_BAD_PARAMETERS; 60 61 memcpy(key->pub, ltc_tmp_key.pub, sizeof(ltc_tmp_key.pub)); 62 memcpy(key->priv, ltc_tmp_key.priv, sizeof(ltc_tmp_key.priv)); 63 memzero_explicit(<c_tmp_key, sizeof(ltc_tmp_key)); 64 65 return TEE_SUCCESS; 66 } 67 68 TEE_Result crypto_acipher_x25519_shared_secret(struct montgomery_keypair 69 *private_key, 70 void *public_key, 71 void *secret, 72 unsigned long *secret_len) 73 { 74 curve25519_key ltc_private_key = { 75 .type = PK_PRIVATE, 76 .algo = LTC_OID_X25519, 77 }; 78 curve25519_key ltc_public_key = { 79 .type = PK_PUBLIC, 80 .algo = LTC_OID_X25519, 81 }; 82 83 if (!private_key || !public_key || !secret || !secret_len) 84 return TEE_ERROR_BAD_PARAMETERS; 85 86 static_assert(sizeof(ltc_public_key.pub) == X25519_KEY_SIZE_BYTES && 87 sizeof(ltc_public_key.priv) == X25519_KEY_SIZE_BYTES); 88 89 memcpy(ltc_public_key.pub, public_key, X25519_KEY_SIZE_BYTES); 90 memcpy(ltc_private_key.priv, private_key->priv, X25519_KEY_SIZE_BYTES); 91 92 if (x25519_shared_secret(<c_private_key, <c_public_key, 93 secret, secret_len) != CRYPT_OK) 94 return TEE_ERROR_BAD_PARAMETERS; 95 96 /* Clear private key from the stack */ 97 memzero_explicit(<c_private_key, sizeof(ltc_private_key)); 98 99 /* 100 * RFC 7748, sec 6.1, check for all zero shared secret output to reject 101 * input points of low order. 102 */ 103 if (*secret_len != X25519_KEY_SIZE_BYTES || 104 !consttime_memcmp(secret, ltc_private_key.pub, 105 X25519_KEY_SIZE_BYTES)) 106 return TEE_ERROR_SECURITY; 107 108 return TEE_SUCCESS; 109 } 110