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, algo); 67 if (res) 68 goto out; 69 70 if (datalen != 0) { 71 res = crypto_hash_update(ctx, algo, data, datalen); 72 if (res) 73 goto out; 74 } 75 76 res = crypto_hash_final(ctx, algo, digest, digestlen); 77 out: 78 crypto_hash_free_ctx(ctx, algo); 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, algo, mode, last_block, data, len, 195 dst); 196 } 197 198 /* 199 * From http://en.wikipedia.org/wiki/Ciphertext_stealing 200 * CBC ciphertext stealing encryption using a standard 201 * CBC interface: 202 * 1. Pad the last partial plaintext block with 0. 203 * 2. Encrypt the whole padded plaintext using the 204 * standard CBC mode. 205 * 3. Swap the last two ciphertext blocks. 206 * 4. Truncate the ciphertext to the length of the 207 * original plaintext. 208 * 209 * CBC ciphertext stealing decryption using a standard 210 * CBC interface 211 * 1. Dn = Decrypt (K, Cn-1). Decrypt the second to last 212 * ciphertext block. 213 * 2. Cn = Cn || Tail (Dn, B-M). Pad the ciphertext to the 214 * nearest multiple of the block size using the last 215 * B-M bits of block cipher decryption of the 216 * second-to-last ciphertext block. 217 * 3. Swap the last two ciphertext blocks. 218 * 4. Decrypt the (modified) ciphertext using the standard 219 * CBC mode. 220 * 5. Truncate the plaintext to the length of the original 221 * ciphertext. 222 */ 223 TEE_Result tee_aes_cbc_cts_update(void *cbc_ctx, void *ecb_ctx, 224 TEE_OperationMode mode, bool last_block, 225 const uint8_t *data, size_t len, 226 uint8_t *dst) 227 { 228 TEE_Result res; 229 int nb_blocks, len_last_block, block_size = 16; 230 uint8_t tmp_block[64], tmp2_block[64]; 231 232 if (!last_block) 233 return tee_do_cipher_update(cbc_ctx, TEE_ALG_AES_CBC_NOPAD, 234 mode, last_block, data, len, dst); 235 236 /* Compute the last block length and check constraints */ 237 nb_blocks = ((len + block_size - 1) / block_size); 238 if (nb_blocks < 2) 239 return TEE_ERROR_BAD_STATE; 240 len_last_block = len % block_size; 241 if (len_last_block == 0) 242 len_last_block = block_size; 243 244 if (mode == TEE_MODE_ENCRYPT) { 245 memcpy(tmp_block, 246 data + ((nb_blocks - 1) * block_size), 247 len_last_block); 248 memset(tmp_block + len_last_block, 249 0, 250 block_size - len_last_block); 251 252 res = tee_do_cipher_update(cbc_ctx, TEE_ALG_AES_CBC_NOPAD, 253 mode, 0, data, 254 (nb_blocks - 1) * block_size, dst); 255 if (res != TEE_SUCCESS) 256 return res; 257 258 memcpy(dst + (nb_blocks - 1) * block_size, 259 dst + (nb_blocks - 2) * block_size, 260 len_last_block); 261 262 res = tee_do_cipher_update(cbc_ctx, TEE_ALG_AES_CBC_NOPAD, 263 mode, 0, tmp_block, block_size, 264 dst + (nb_blocks - 2) * block_size); 265 if (res != TEE_SUCCESS) 266 return res; 267 } else { 268 /* 1. Decrypt the second to last ciphertext block */ 269 res = tee_do_cipher_update(ecb_ctx, TEE_ALG_AES_ECB_NOPAD, 270 mode, 0, 271 data + (nb_blocks - 2) * block_size, 272 block_size, tmp2_block); 273 if (res != TEE_SUCCESS) 274 return res; 275 276 /* 2. Cn = Cn || Tail (Dn, B-M) */ 277 memcpy(tmp_block, data + ((nb_blocks - 1) * block_size), 278 len_last_block); 279 memcpy(tmp_block + len_last_block, tmp2_block + len_last_block, 280 block_size - len_last_block); 281 282 /* 3. Swap the last two ciphertext blocks */ 283 /* done by passing the correct buffers in step 4. */ 284 285 /* 4. Decrypt the (modified) ciphertext */ 286 if (nb_blocks > 2) { 287 res = tee_do_cipher_update(cbc_ctx, 288 TEE_ALG_AES_CBC_NOPAD, mode, 289 0, data, 290 (nb_blocks - 2) * 291 block_size, dst); 292 if (res != TEE_SUCCESS) 293 return res; 294 } 295 296 res = tee_do_cipher_update(cbc_ctx, TEE_ALG_AES_CBC_NOPAD, 297 mode, 0, tmp_block, block_size, 298 dst + 299 ((nb_blocks - 2) * block_size)); 300 if (res != TEE_SUCCESS) 301 return res; 302 303 res = tee_do_cipher_update(cbc_ctx, TEE_ALG_AES_CBC_NOPAD, 304 mode, 0, data + 305 ((nb_blocks - 2) * block_size), 306 block_size, tmp_block); 307 if (res != TEE_SUCCESS) 308 return res; 309 310 /* 5. Truncate the plaintext */ 311 memcpy(dst + (nb_blocks - 1) * block_size, tmp_block, 312 len_last_block); 313 } 314 return TEE_SUCCESS; 315 } 316 317 /* 318 * Override this in your platform code to feed the PRNG platform-specific 319 * jitter entropy. This implementation does not efficiently deliver entropy 320 * and is here for backwards-compatibility. 321 */ 322 __weak void plat_prng_add_jitter_entropy(enum crypto_rng_src sid, 323 unsigned int *pnum) 324 { 325 TEE_Time current; 326 327 #ifdef CFG_SECURE_TIME_SOURCE_REE 328 if (CRYPTO_RNG_SRC_IS_QUICK(sid)) 329 return; /* Can't read REE time here */ 330 #endif 331 332 if (tee_time_get_sys_time(¤t) == TEE_SUCCESS) 333 crypto_rng_add_event(sid, pnum, ¤t, sizeof(current)); 334 } 335 336 __weak void plat_rng_init(void) 337 { 338 TEE_Result res = TEE_SUCCESS; 339 TEE_Time t; 340 341 #ifndef CFG_SECURE_TIME_SOURCE_REE 342 /* 343 * This isn't much of a seed. Ideally we should either get a seed from 344 * a hardware RNG or from a previously saved seed. 345 * 346 * Seeding with hardware RNG is currently up to the platform to 347 * override this function. 348 * 349 * Seeding with a saved seed will require cooperation from normal 350 * world, this is still TODO. 351 */ 352 res = tee_time_get_sys_time(&t); 353 #else 354 EMSG("Warning: seeding RNG with zeroes"); 355 memset(&t, 0, sizeof(t)); 356 #endif 357 if (!res) 358 res = crypto_rng_init(&t, sizeof(t)); 359 if (res) { 360 EMSG("Failed to initialize RNG: %#" PRIx32, res); 361 panic(); 362 } 363 } 364 365 static TEE_Result tee_cryp_init(void) 366 { 367 TEE_Result res = crypto_init(); 368 369 if (res) { 370 EMSG("Failed to initialize crypto API: %#" PRIx32, res); 371 panic(); 372 } 373 plat_rng_init(); 374 375 return TEE_SUCCESS; 376 } 377 service_init(tee_cryp_init); 378