1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2024, Siemens AG
4  * All rights reserved.
5  * Copyright (c) 2024, Linaro Limited
6  */
7 
8 #include "Tpm.h"
9 #include <tee_internal_api.h>
10 #include <stdint.h>
11 #include <string.h>
12 
13 /*
14  * TEE_SetKeyAES() - Set AES key.
15  * @ks	pointer to space for storing the key schedule
16  * @key	pointer to the key
17  * @sz	length of the key in bytes
18  *
19  * There is no "finalize" function, so we can't allocate  the key schedule
20  * here, because we could never free it.
21  *
22  * return 0 if ok, any other value otherwise
23  */
TEE_SetKeyAES(tpmKeyScheduleAES * ks,const uint8_t * key,uint16_t sz)24 int TEE_SetKeyAES(tpmKeyScheduleAES *ks, const uint8_t *key, uint16_t sz)
25 {
26 	if (sz == 16 || sz == 24 || sz == 32) {
27 		ks->keySizeInBytes = sz;
28 		memcpy(ks->key, key, sz);
29 		return 0;
30 	} else {
31 		return 1;
32 	}
33 }
34 
35 /*
36  * TEE_SetKeyTDES() - Set DES key.
37  * @ks	pointer to space for storing the key schedule
38  * @key	pointer to the key
39  * @sz	length of the key in bytes
40  *
41  * There is no "finalize" function, so we can't allocate  the key schedule
42  * here, because we could never free it.
43  *
44  * return 0 if ok, any other value otherwise
45  */
TEE_SetKeyTDES(tpmKeyScheduleTDES * ks,const uint8_t * key,uint16_t sz)46 int TEE_SetKeyTDES(tpmKeyScheduleTDES *ks, const uint8_t *key, uint16_t sz)
47 {
48 	if (sz == 16 || sz == 24) {
49 		ks->keySizeInBytes = sz;
50 		memcpy(ks->key, key, sz);
51 		return 0;
52 	} else {
53 		return 1;
54 	}
55 }
56 
57 /*
58  * TEE_SetKeySM4() - Set SM4 key.
59  * @ks	pointer to space for storing the key schedule
60  * @key	pointer to the key
61  * @sz	length of the key in bytes
62  *
63  * return 0 if ok, any other value otherwise
64  *
65  * There is no "finalize" function, so we can't allocate  the key schedule
66  * here, because we could never free it.
67  */
TEE_SetKeySM4(tpmKeyScheduleSM4 * ks,const uint8_t * key,uint16_t sz)68 int TEE_SetKeySM4(tpmKeyScheduleSM4 *ks, const uint8_t *key, uint16_t sz)
69 {
70 	if (sz == 16) {
71 		ks->keySizeInBytes = sz;
72 		memcpy(ks->key, key, sz);
73 		return 0;
74 	} else {
75 		return 1;
76 	}
77 }
78 
79 /*
80  * The functions calling this function can't return an error so neither can
81  * this. In case of error we panic since the alternative is to carry out
82  * the operation incorrectly.
83  */
block_op(uint8_t * out,uint32_t algo,uint32_t mode,size_t block_size,TEE_ObjectType obj_type,const uint8_t * key,uint16_t keySizeInBytes,const uint8_t * in)84 static void block_op(uint8_t *out, uint32_t algo, uint32_t mode,
85 		     size_t block_size, TEE_ObjectType obj_type,
86 		     const uint8_t *key, uint16_t keySizeInBytes,
87 		     const uint8_t *in)
88 {
89 	TEE_OperationHandle op = TEE_HANDLE_NULL;
90 	TEE_ObjectHandle obj = TEE_HANDLE_NULL;
91 	TEE_Result res = TEE_SUCCESS;
92 	size_t outlen = block_size;
93 	TEE_Attribute attr = {};
94 
95 	res = TEE_AllocateTransientObject(obj_type, 8 * keySizeInBytes, &obj);
96 	if (res)
97 		TEE_Panic(res);
98 
99 	TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, keySizeInBytes);
100 	res = TEE_PopulateTransientObject(obj, &attr, 1);
101 	if (res)
102 		TEE_Panic(res);
103 
104 	res = TEE_AllocateOperation(&op, algo, mode, 8 * keySizeInBytes);
105 	if (res)
106 		TEE_Panic(res);
107 
108 	res = TEE_SetOperationKey(op, obj);
109 	if (res)
110 		TEE_Panic(res);
111 
112 	TEE_CipherInit(op, 0, 0);
113 	outlen = block_size;
114 	res = TEE_CipherDoFinal(op, in, block_size, out, &outlen);
115 	if (res)
116 		TEE_Panic(res);
117 
118 	TEE_FreeOperation(op);
119 	TEE_FreeTransientObject(obj);
120 }
121 
TEE_AESEncrypt(uint8_t * out,const tpmKeyScheduleAES * ks,const uint8_t * in)122 void TEE_AESEncrypt(uint8_t *out, const tpmKeyScheduleAES *ks,
123 		    const uint8_t *in)
124 {
125 	block_op(out, TEE_ALG_AES_ECB_NOPAD, TEE_MODE_ENCRYPT, 16, TEE_TYPE_AES,
126 		 ks->key, ks->keySizeInBytes, in);
127 }
128 
TEE_AESDecrypt(uint8_t * out,const tpmKeyScheduleAES * ks,const uint8_t * in)129 void TEE_AESDecrypt(uint8_t *out, const tpmKeyScheduleAES *ks,
130 		    const uint8_t *in)
131 {
132 	block_op(out, TEE_ALG_AES_ECB_NOPAD, TEE_MODE_DECRYPT, 16, TEE_TYPE_AES,
133 		 ks->key, ks->keySizeInBytes, in);
134 }
135 
TEE_TDESEncrypt(uint8_t * out,const tpmKeyScheduleTDES * ks,const uint8_t * in)136 void TEE_TDESEncrypt(uint8_t *out, const tpmKeyScheduleTDES *ks,
137 		     const uint8_t *in)
138 {
139 	block_op(out, TEE_ALG_DES3_ECB_NOPAD, TEE_MODE_ENCRYPT, 8,
140 		 TEE_TYPE_DES3, ks->key, ks->keySizeInBytes, in);
141 }
142 
TEE_TDESDecrypt(uint8_t * out,const tpmKeyScheduleTDES * ks,const uint8_t * in)143 void TEE_TDESDecrypt(uint8_t *out, const tpmKeyScheduleTDES *ks,
144 		     const uint8_t *in)
145 {
146 	block_op(out, TEE_ALG_DES3_ECB_NOPAD, TEE_MODE_DECRYPT, 8,
147 		 TEE_TYPE_DES3, ks->key, ks->keySizeInBytes, in);
148 }
149 
TEE_SM4Encrypt(uint8_t * out,const tpmKeyScheduleSM4 * ks,const uint8_t * in)150 void TEE_SM4Encrypt(uint8_t *out, const tpmKeyScheduleSM4 *ks,
151 		    const uint8_t *in)
152 {
153 	block_op(out, TEE_ALG_SM4_ECB_NOPAD, TEE_MODE_ENCRYPT, 16, TEE_TYPE_SM4,
154 		 ks->key, ks->keySizeInBytes, in);
155 }
156 
TEE_SM4Decrypt(uint8_t * out,const tpmKeyScheduleSM4 * ks,const uint8_t * in)157 void TEE_SM4Decrypt(uint8_t *out, const tpmKeyScheduleSM4 *ks,
158 		    const uint8_t *in)
159 {
160 	block_op(out, TEE_ALG_SM4_ECB_NOPAD, TEE_MODE_DECRYPT, 16, TEE_TYPE_SM4,
161 		 ks->key, ks->keySizeInBytes, in);
162 }
163