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