1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, Linaro Limited 4 */ 5 6 #include <crypto/crypto.h> 7 #include <initcall.h> 8 #include <kernel/panic.h> 9 #include <kernel/tee_time.h> 10 #include <rng_support.h> 11 #include <stdlib.h> 12 #include <string_ext.h> 13 #include <string.h> 14 #include <tee/tee_cryp_utl.h> 15 #include <trace.h> 16 #include <utee_defines.h> 17 18 TEE_Result tee_hash_get_digest_size(uint32_t algo, size_t *size) 19 { 20 switch (algo) { 21 case TEE_ALG_MD5: 22 case TEE_ALG_HMAC_MD5: 23 *size = TEE_MD5_HASH_SIZE; 24 break; 25 case TEE_ALG_SHA1: 26 case TEE_ALG_HMAC_SHA1: 27 case TEE_ALG_DSA_SHA1: 28 *size = TEE_SHA1_HASH_SIZE; 29 break; 30 case TEE_ALG_SHA224: 31 case TEE_ALG_HMAC_SHA224: 32 case TEE_ALG_DSA_SHA224: 33 *size = TEE_SHA224_HASH_SIZE; 34 break; 35 case TEE_ALG_SHA256: 36 case TEE_ALG_HMAC_SHA256: 37 case TEE_ALG_DSA_SHA256: 38 *size = TEE_SHA256_HASH_SIZE; 39 break; 40 case TEE_ALG_SHA384: 41 case TEE_ALG_HMAC_SHA384: 42 *size = TEE_SHA384_HASH_SIZE; 43 break; 44 case TEE_ALG_SHA512: 45 case TEE_ALG_HMAC_SHA512: 46 *size = TEE_SHA512_HASH_SIZE; 47 break; 48 case TEE_ALG_SM3: 49 case TEE_ALG_HMAC_SM3: 50 *size = TEE_SM3_HASH_SIZE; 51 break; 52 default: 53 return TEE_ERROR_NOT_SUPPORTED; 54 } 55 56 return TEE_SUCCESS; 57 } 58 59 TEE_Result tee_hash_createdigest(uint32_t algo, const uint8_t *data, 60 size_t datalen, uint8_t *digest, 61 size_t digestlen) 62 { 63 TEE_Result res; 64 void *ctx = NULL; 65 66 res = crypto_hash_alloc_ctx(&ctx, algo); 67 if (res) 68 return res; 69 70 res = crypto_hash_init(ctx); 71 if (res) 72 goto out; 73 74 if (datalen != 0) { 75 res = crypto_hash_update(ctx, data, datalen); 76 if (res) 77 goto out; 78 } 79 80 res = crypto_hash_final(ctx, digest, digestlen); 81 out: 82 crypto_hash_free_ctx(ctx); 83 84 return res; 85 } 86 87 TEE_Result tee_mac_get_digest_size(uint32_t algo, size_t *size) 88 { 89 switch (algo) { 90 case TEE_ALG_HMAC_MD5: 91 case TEE_ALG_HMAC_SHA224: 92 case TEE_ALG_HMAC_SHA1: 93 case TEE_ALG_HMAC_SHA256: 94 case TEE_ALG_HMAC_SHA384: 95 case TEE_ALG_HMAC_SHA512: 96 case TEE_ALG_HMAC_SM3: 97 return tee_hash_get_digest_size(algo, size); 98 case TEE_ALG_AES_CBC_MAC_NOPAD: 99 case TEE_ALG_AES_CBC_MAC_PKCS5: 100 case TEE_ALG_AES_CMAC: 101 *size = TEE_AES_BLOCK_SIZE; 102 return TEE_SUCCESS; 103 case TEE_ALG_DES_CBC_MAC_NOPAD: 104 case TEE_ALG_DES_CBC_MAC_PKCS5: 105 case TEE_ALG_DES3_CBC_MAC_NOPAD: 106 case TEE_ALG_DES3_CBC_MAC_PKCS5: 107 *size = TEE_DES_BLOCK_SIZE; 108 return TEE_SUCCESS; 109 default: 110 return TEE_ERROR_NOT_SUPPORTED; 111 } 112 } 113 114 TEE_Result tee_cipher_get_block_size(uint32_t algo, size_t *size) 115 { 116 switch (algo) { 117 case TEE_ALG_AES_CBC_MAC_NOPAD: 118 case TEE_ALG_AES_CBC_MAC_PKCS5: 119 case TEE_ALG_AES_CMAC: 120 case TEE_ALG_AES_ECB_NOPAD: 121 case TEE_ALG_AES_CBC_NOPAD: 122 case TEE_ALG_AES_CTR: 123 case TEE_ALG_AES_CTS: 124 case TEE_ALG_AES_XTS: 125 case TEE_ALG_AES_CCM: 126 case TEE_ALG_AES_GCM: 127 case TEE_ALG_SM4_ECB_NOPAD: 128 case TEE_ALG_SM4_CBC_NOPAD: 129 case TEE_ALG_SM4_CTR: 130 *size = 16; 131 break; 132 133 case TEE_ALG_DES_CBC_MAC_NOPAD: 134 case TEE_ALG_DES_CBC_MAC_PKCS5: 135 case TEE_ALG_DES_ECB_NOPAD: 136 case TEE_ALG_DES_CBC_NOPAD: 137 case TEE_ALG_DES3_CBC_MAC_NOPAD: 138 case TEE_ALG_DES3_CBC_MAC_PKCS5: 139 case TEE_ALG_DES3_ECB_NOPAD: 140 case TEE_ALG_DES3_CBC_NOPAD: 141 *size = 8; 142 break; 143 144 default: 145 return TEE_ERROR_NOT_SUPPORTED; 146 } 147 148 return TEE_SUCCESS; 149 } 150 151 TEE_Result tee_do_cipher_update(void *ctx, uint32_t algo, 152 TEE_OperationMode mode, bool last_block, 153 const uint8_t *data, size_t len, uint8_t *dst) 154 { 155 TEE_Result res; 156 size_t block_size; 157 158 if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) 159 return TEE_ERROR_BAD_PARAMETERS; 160 161 /* 162 * Check that the block contains the correct number of data, apart 163 * for the last block in some XTS / CTR / XTS mode 164 */ 165 res = tee_cipher_get_block_size(algo, &block_size); 166 if (res != TEE_SUCCESS) 167 return res; 168 if ((len % block_size) != 0) { 169 if (!last_block && algo != TEE_ALG_AES_CTR) 170 return TEE_ERROR_BAD_PARAMETERS; 171 172 switch (algo) { 173 case TEE_ALG_AES_ECB_NOPAD: 174 case TEE_ALG_DES_ECB_NOPAD: 175 case TEE_ALG_DES3_ECB_NOPAD: 176 case TEE_ALG_AES_CBC_NOPAD: 177 case TEE_ALG_DES_CBC_NOPAD: 178 case TEE_ALG_DES3_CBC_NOPAD: 179 case TEE_ALG_SM4_ECB_NOPAD: 180 case TEE_ALG_SM4_CBC_NOPAD: 181 return TEE_ERROR_BAD_PARAMETERS; 182 183 case TEE_ALG_AES_CTR: 184 case TEE_ALG_AES_XTS: 185 case TEE_ALG_AES_CTS: 186 /* 187 * These modes doesn't require padding for the last 188 * block. 189 * 190 * This isn't entirely true, both XTS and CTS can only 191 * encrypt minimum one block and also they need at least 192 * one complete block in the last update to finish the 193 * encryption. The algorithms are supposed to detect 194 * that, we're only making sure that all data fed up to 195 * that point consists of complete blocks. 196 */ 197 break; 198 199 default: 200 return TEE_ERROR_NOT_SUPPORTED; 201 } 202 } 203 204 return crypto_cipher_update(ctx, mode, last_block, data, len, dst); 205 } 206 207 /* 208 * Override this in your platform code to feed the PRNG platform-specific 209 * jitter entropy. This implementation does not efficiently deliver entropy 210 * and is here for backwards-compatibility. 211 */ 212 __weak void plat_prng_add_jitter_entropy(enum crypto_rng_src sid, 213 unsigned int *pnum) 214 { 215 TEE_Time current; 216 217 #ifdef CFG_SECURE_TIME_SOURCE_REE 218 if (CRYPTO_RNG_SRC_IS_QUICK(sid)) 219 return; /* Can't read REE time here */ 220 #endif 221 222 if (tee_time_get_sys_time(¤t) == TEE_SUCCESS) 223 crypto_rng_add_event(sid, pnum, ¤t, sizeof(current)); 224 } 225 226 __weak void plat_rng_init(void) 227 { 228 TEE_Result res = TEE_SUCCESS; 229 TEE_Time t; 230 231 #ifndef CFG_SECURE_TIME_SOURCE_REE 232 /* 233 * This isn't much of a seed. Ideally we should either get a seed from 234 * a hardware RNG or from a previously saved seed. 235 * 236 * Seeding with hardware RNG is currently up to the platform to 237 * override this function. 238 * 239 * Seeding with a saved seed will require cooperation from normal 240 * world, this is still TODO. 241 */ 242 res = tee_time_get_sys_time(&t); 243 #else 244 EMSG("Warning: seeding RNG with zeroes"); 245 memset(&t, 0, sizeof(t)); 246 #endif 247 if (!res) 248 res = crypto_rng_init(&t, sizeof(t)); 249 if (res) { 250 EMSG("Failed to initialize RNG: %#" PRIx32, res); 251 panic(); 252 } 253 } 254 255 static TEE_Result tee_cryp_init(void) 256 { 257 TEE_Result res = crypto_init(); 258 259 if (res) { 260 EMSG("Failed to initialize crypto API: %#" PRIx32, res); 261 panic(); 262 } 263 plat_rng_init(); 264 265 return TEE_SUCCESS; 266 } 267 service_init(tee_cryp_init); 268