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