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_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 /* 134 * These modes doesn't require padding for the last 135 * block. 136 * 137 * This isn't entirely true, both XTS and CTS can only 138 * encrypt minimum one block and also they need at least 139 * one complete block in the last update to finish the 140 * encryption. The algorithms are supposed to detect 141 * that, we're only making sure that all data fed up to 142 * that point consists of complete blocks. 143 */ 144 break; 145 146 default: 147 return TEE_ERROR_NOT_SUPPORTED; 148 } 149 } 150 151 return crypto_cipher_update(ctx, mode, last_block, data, len, dst); 152 } 153 154 /* 155 * Override this in your platform code to feed the PRNG platform-specific 156 * jitter entropy. This implementation does not efficiently deliver entropy 157 * and is here for backwards-compatibility. 158 */ 159 __weak void plat_prng_add_jitter_entropy(enum crypto_rng_src sid, 160 unsigned int *pnum) 161 { 162 TEE_Time current; 163 164 #ifdef CFG_SECURE_TIME_SOURCE_REE 165 if (CRYPTO_RNG_SRC_IS_QUICK(sid)) 166 return; /* Can't read REE time here */ 167 #endif 168 169 if (tee_time_get_sys_time(¤t) == TEE_SUCCESS) 170 crypto_rng_add_event(sid, pnum, ¤t, sizeof(current)); 171 } 172 173 __weak void plat_rng_init(void) 174 { 175 TEE_Result res = TEE_SUCCESS; 176 TEE_Time t; 177 178 #ifndef CFG_SECURE_TIME_SOURCE_REE 179 /* 180 * This isn't much of a seed. Ideally we should either get a seed from 181 * a hardware RNG or from a previously saved seed. 182 * 183 * Seeding with hardware RNG is currently up to the platform to 184 * override this function. 185 * 186 * Seeding with a saved seed will require cooperation from normal 187 * world, this is still TODO. 188 */ 189 res = tee_time_get_sys_time(&t); 190 #else 191 EMSG("Warning: seeding RNG with zeroes"); 192 memset(&t, 0, sizeof(t)); 193 #endif 194 if (!res) 195 res = crypto_rng_init(&t, sizeof(t)); 196 if (res) { 197 EMSG("Failed to initialize RNG: %#" PRIx32, res); 198 panic(); 199 } 200 } 201 202 static TEE_Result tee_cryp_init(void) 203 { 204 TEE_Result res = crypto_init(); 205 206 if (res) { 207 EMSG("Failed to initialize crypto API: %#" PRIx32, res); 208 panic(); 209 } 210 plat_rng_init(); 211 212 dt_driver_crypt_init_complete(); 213 214 return TEE_SUCCESS; 215 } 216 service_init(tee_cryp_init); 217