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