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