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