1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2018-2021 NXP
4 *
5 * Crypto DH interface implementation to enable HW driver.
6 */
7 #include <crypto/crypto.h>
8 #include <drvcrypt.h>
9 #include <drvcrypt_acipher.h>
10 #include <malloc.h>
11
crypto_acipher_alloc_dh_keypair(struct dh_keypair * key,size_t size_bits)12 TEE_Result crypto_acipher_alloc_dh_keypair(struct dh_keypair *key,
13 size_t size_bits)
14 {
15 TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
16 struct drvcrypt_dh *dh = NULL;
17
18 if (!key || !size_bits) {
19 CRYPTO_TRACE("Param error key @%#" PRIxPTR " size %zu bits",
20 (uintptr_t)key, size_bits);
21 return TEE_ERROR_BAD_PARAMETERS;
22 }
23
24 dh = drvcrypt_get_ops(CRYPTO_DH);
25 if (dh)
26 ret = dh->alloc_keypair(key, size_bits);
27
28 CRYPTO_TRACE("DH Keypair (%zu bits) alloc ret = 0x%" PRIx32, size_bits,
29 ret);
30 return ret;
31 }
32
crypto_acipher_gen_dh_key(struct dh_keypair * key,struct bignum * q,size_t xbits,size_t key_size)33 TEE_Result crypto_acipher_gen_dh_key(struct dh_keypair *key, struct bignum *q,
34 size_t xbits, size_t key_size)
35 {
36 TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
37 struct drvcrypt_dh *dh = NULL;
38
39 if (!key) {
40 CRYPTO_TRACE("Parameters error key is NULL");
41 return TEE_ERROR_BAD_PARAMETERS;
42 }
43
44 if (key_size != 8 * crypto_bignum_num_bytes(key->p))
45 return TEE_ERROR_BAD_PARAMETERS;
46
47 dh = drvcrypt_get_ops(CRYPTO_DH);
48 if (dh)
49 ret = dh->gen_keypair(key, q, xbits);
50
51 CRYPTO_TRACE("DH Keypair (%zu bits) generate ret = 0x%" PRIx32,
52 key_size, ret);
53
54 return ret;
55 }
56
crypto_acipher_dh_shared_secret(struct dh_keypair * private_key,struct bignum * public_key,struct bignum * secret)57 TEE_Result crypto_acipher_dh_shared_secret(struct dh_keypair *private_key,
58 struct bignum *public_key,
59 struct bignum *secret)
60 {
61 TEE_Result ret = TEE_ERROR_BAD_PARAMETERS;
62 struct drvcrypt_dh *dh = NULL;
63 struct drvcrypt_secret_data sdata = { };
64 uint8_t *secret_buf = NULL;
65
66 if (!private_key || !public_key || !secret) {
67 CRYPTO_TRACE("Input parameters reference error");
68 return TEE_ERROR_BAD_PARAMETERS;
69 }
70
71 dh = drvcrypt_get_ops(CRYPTO_DH);
72 if (dh) {
73 /* Allocate the binary Secret buffer */
74 sdata.secret.length = crypto_bignum_num_bytes(public_key);
75 secret_buf = malloc(sdata.secret.length);
76 if (!secret_buf)
77 return TEE_ERROR_OUT_OF_MEMORY;
78
79 /* Prepare the Secret structure data */
80 sdata.key_priv = private_key;
81 sdata.key_pub = public_key;
82 sdata.secret.data = secret_buf;
83
84 ret = dh->shared_secret(&sdata);
85 if (ret == TEE_SUCCESS)
86 ret = crypto_bignum_bin2bn(secret_buf,
87 sdata.secret.length, secret);
88
89 free(secret_buf);
90 } else {
91 ret = TEE_ERROR_NOT_IMPLEMENTED;
92 }
93
94 CRYPTO_TRACE("Shared Secret returned 0x%" PRIx32, ret);
95
96 return ret;
97 }
98