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