diff --git a/bdk/sec/se.c b/bdk/sec/se.c index 4ed04ecf..04495d07 100644 --- a/bdk/sec/se.c +++ b/bdk/sec/se.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2025 CTCaer + * Copyright (c) 2018-2026 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -27,60 +27,54 @@ typedef struct _se_ll_t { - vu32 num; - vu32 addr; - vu32 size; + u32 num; + u32 addr; + u32 size; } se_ll_t; -se_ll_t ll_src, ll_dst; -se_ll_t *ll_src_ptr, *ll_dst_ptr; // Must be u32 aligned. +se_ll_t ll_src, ll_dst; // Must be u32 aligned. +se_ll_t *ll_src_ptr, *ll_dst_ptr; -static void _gf256_mul_x(void *block) +static void _se_ls_1bit(void *buf) { - u8 *pdata = (u8 *)block; + u8 *block = (u8 *)buf; u32 carry = 0; - for (int i = 0xF; i >= 0; i--) + for (int i = SE_AES_BLOCK_SIZE - 1; i >= 0; i--) { - u8 b = pdata[i]; - pdata[i] = (b << 1) | carry; + u8 b = block[i]; + block[i] = (b << 1) | carry; carry = b >> 7; } if (carry) - pdata[0xF] ^= 0x87; + block[SE_AES_BLOCK_SIZE - 1] ^= 0x87; } -static void _gf256_mul_x_le(void *block) +static void _se_ls_1bit_le(void *buf) { - u32 *pdata = (u32 *)block; + u32 *block = (u32 *)buf; u32 carry = 0; for (u32 i = 0; i < 4; i++) { - u32 b = pdata[i]; - pdata[i] = (b << 1) | carry; + u32 b = block[i]; + block[i] = (b << 1) | carry; carry = b >> 31; } if (carry) - pdata[0x0] ^= 0x87; + block[0x0] ^= 0x87; } -static void _se_ll_init(se_ll_t *ll, u32 addr, u32 size) +static void _se_ll_set(se_ll_t *ll, u32 addr, u32 size) { ll->num = 0; ll->addr = addr; - ll->size = size; + ll->size = size & 0xFFFFFF; } -static void _se_ll_set(se_ll_t *src, se_ll_t *dst) -{ - SE(SE_IN_LL_ADDR_REG) = (u32)src; - SE(SE_OUT_LL_ADDR_REG) = (u32)dst; -} - -static int _se_wait() +static int _se_op_wait() { bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210; @@ -127,14 +121,11 @@ static int _se_wait() static int _se_execute_finalize() { - int res = _se_wait(); + int res = _se_op_wait(); // Invalidate data after OP is done. bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false); - ll_src_ptr = NULL; - ll_dst_ptr = NULL; - return res; } @@ -146,17 +137,20 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src if (src) { ll_src_ptr = &ll_src; - _se_ll_init(ll_src_ptr, (u32)src, src_size); + _se_ll_set(ll_src_ptr, (u32)src, src_size); } if (dst) { ll_dst_ptr = &ll_dst; - _se_ll_init(ll_dst_ptr, (u32)dst, dst_size); + _se_ll_set(ll_dst_ptr, (u32)dst, dst_size); } - _se_ll_set(ll_src_ptr, ll_dst_ptr); + // Set linked list pointers. + SE(SE_IN_LL_ADDR_REG) = (u32)ll_src_ptr; + SE(SE_OUT_LL_ADDR_REG) = (u32)ll_dst_ptr; + // Clear status. SE(SE_ERR_STATUS_REG) = SE(SE_ERR_STATUS_REG); SE(SE_INT_STATUS_REG) = SE(SE_INT_STATUS_REG); @@ -183,7 +177,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr u32 block[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0}; - SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1; + SE(SE_CRYPTO_LAST_BLOCK_REG) = 1 - 1; memcpy(block, src, src_size); int res = _se_execute_oneshot(op, block, SE_AES_BLOCK_SIZE, block, SE_AES_BLOCK_SIZE); @@ -192,19 +186,19 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr return res; } -static void _se_aes_ctr_set(const void *ctr) +static void _se_aes_counter_set(const void *ctr) { - u32 data[SE_AES_IV_SIZE / 4]; + u32 data[SE_AES_IV_SIZE / sizeof(u32)]; memcpy(data, ctr, SE_AES_IV_SIZE); for (u32 i = 0; i < SE_CRYPTO_LINEAR_CTR_REG_COUNT; i++) - SE(SE_CRYPTO_LINEAR_CTR_REG + (4 * i)) = data[i]; + SE(SE_CRYPTO_LINEAR_CTR_REG + sizeof(u32) * i) = data[i]; } void se_rsa_acc_ctrl(u32 rs, u32 flags) { if (flags & SE_RSA_KEY_TBL_DIS_KEY_ACCESS_FLAG) - SE(SE_RSA_KEYTABLE_ACCESS_REG + 4 * rs) = + SE(SE_RSA_KEYTABLE_ACCESS_REG + sizeof(u32) * rs) = (((flags >> 4) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) | (flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG)) ^ SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_USE_FLAG; if (flags & SE_RSA_KEY_LOCK_FLAG) @@ -214,34 +208,35 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags) void se_key_acc_ctrl(u32 ks, u32 flags) { if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG) - SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks) = ~flags; + SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + sizeof(u32) * ks) = ~flags; if (flags & SE_KEY_LOCK_FLAG) SE(SE_CRYPTO_SECURITY_PERKEY_REG) &= ~BIT(ks); } u32 se_key_acc_ctrl_get(u32 ks) { - return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + 4 * ks); + return SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + sizeof(u32) * ks); } void se_aes_key_set(u32 ks, const void *key, u32 size) { - u32 data[SE_AES_MAX_KEY_SIZE / 4]; + u32 data[SE_AES_MAX_KEY_SIZE / sizeof(u32)]; memcpy(data, key, size); - for (u32 i = 0; i < (size / 4); i++) + for (u32 i = 0; i < (size / sizeof(u32)); i++) { - SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT. + // QUAD KEYS_4_7 bit is automatically set by PKT macro. + SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(KEYS_0_3) | SE_KEYTABLE_PKT(i); SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i]; } } void se_aes_iv_set(u32 ks, const void *iv) { - u32 data[SE_AES_IV_SIZE / 4]; + u32 data[SE_AES_IV_SIZE / sizeof(u32)]; memcpy(data, iv, SE_AES_IV_SIZE); - for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++) + for (u32 i = 0; i < (SE_AES_IV_SIZE / sizeof(u32)); i++) { SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i); SE(SE_CRYPTO_KEYTABLE_DATA_REG) = data[i]; @@ -250,11 +245,12 @@ void se_aes_iv_set(u32 ks, const void *iv) void se_aes_key_get(u32 ks, void *key, u32 size) { - u32 data[SE_AES_MAX_KEY_SIZE / 4]; + u32 data[SE_AES_MAX_KEY_SIZE / sizeof(u32)]; - for (u32 i = 0; i < (size / 4); i++) + for (u32 i = 0; i < (size / sizeof(u32)); i++) { - SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT. + // QUAD KEYS_4_7 bit is automatically set by PKT macro. + SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(KEYS_0_3) | SE_KEYTABLE_PKT(i); data[i] = SE(SE_CRYPTO_KEYTABLE_DATA_REG); } @@ -263,16 +259,17 @@ void se_aes_key_get(u32 ks, void *key, u32 size) void se_aes_key_clear(u32 ks) { - for (u32 i = 0; i < (SE_AES_MAX_KEY_SIZE / 4); i++) + for (u32 i = 0; i < (SE_AES_MAX_KEY_SIZE / sizeof(u32)); i++) { - SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_PKT(i); // QUAD is automatically set by PKT. + // QUAD KEYS_4_7 bit is automatically set by PKT macro. + SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(KEYS_0_3) | SE_KEYTABLE_PKT(i); SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0; } } void se_aes_iv_clear(u32 ks) { - for (u32 i = 0; i < (SE_AES_IV_SIZE / 4); i++) + for (u32 i = 0; i < (SE_AES_IV_SIZE / sizeof(u32)); i++) { SE(SE_CRYPTO_KEYTABLE_ADDR_REG) = SE_KEYTABLE_SLOT(ks) | SE_KEYTABLE_QUAD(ORIGINAL_IV) | SE_KEYTABLE_PKT(i); SE(SE_CRYPTO_KEYTABLE_DATA_REG) = 0; @@ -288,17 +285,17 @@ void se_aes_iv_updated_clear(u32 ks) } } -int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input) +int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *seed) { - SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); - SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1; + SE(SE_CONFIG_REG) = SE_CONFIG_DEC_MODE(MODE_KEY128) | SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_KEYTABLE); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks_src) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); + SE(SE_CRYPTO_LAST_BLOCK_REG) = (SE_AES_BLOCK_SIZE >> 4) - 1; SE(SE_CRYPTO_KEYTABLE_DST_REG) = SE_KEYTABLE_DST_KEY_INDEX(ks_dst) | SE_KEYTABLE_DST_WORD_QUAD(KEYS_0_3); - return _se_execute_oneshot(SE_OP_START, NULL, 0, input, SE_KEY_128_SIZE); + return _se_execute_oneshot(SE_OP_START, NULL, 0, seed, SE_KEY_128_SIZE); } -int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size) +int se_aes_crypt_hash(u32 ks, int enc, void *dst, u32 dst_size, const void *src, u32 src_size) { if (enc) { @@ -314,64 +311,67 @@ int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_HASH(HASH_ENABLE); } - SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1; + SE(SE_CRYPTO_LAST_BLOCK_REG) = (src_size >> 4) - 1; return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size); } -int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size) +int se_aes_crypt_ecb(u32 ks, int enc, void *dst, u32 dst_size, const void *src, u32 src_size) { if (enc) { - SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT); + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | + SE_CRYPTO_XOR_POS(XOR_BYPASS); } else { - SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); + SE(SE_CONFIG_REG) = SE_CONFIG_DEC_MODE(MODE_KEY128) | SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | + SE_CRYPTO_XOR_POS(XOR_BYPASS); } - SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1; + SE(SE_CRYPTO_LAST_BLOCK_REG) = (src_size >> 4) - 1; return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size); } -int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size) +int se_aes_crypt_cbc(u32 ks, int enc, void *dst, u32 dst_size, const void *src, u32 src_size) { if (enc) { - SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_AESOUT) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | SE_CRYPTO_XOR_POS(XOR_TOP); } else { - SE(SE_CONFIG_REG) = SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CONFIG_REG) = SE_CONFIG_DEC_MODE(MODE_KEY128) | SE_CONFIG_DEC_ALG(ALG_AES_DEC) | SE_CONFIG_DST(DST_MEMORY); SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_VCTRAM_SEL(VCTRAM_PREVMEM) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT) | SE_CRYPTO_XOR_POS(XOR_BOTTOM); } - SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1; + SE(SE_CRYPTO_LAST_BLOCK_REG) = (src_size >> 4) - 1; return _se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size); } -int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src) +int se_aes_crypt_block_ecb(u32 ks, int enc, void *dst, const void *src) { return se_aes_crypt_ecb(ks, enc, dst, SE_AES_BLOCK_SIZE, src, SE_AES_BLOCK_SIZE); } int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr) { - SE(SE_SPARE_REG) = SE_ECO(SE_ERRATA_FIX_ENABLE); - SE(SE_CONFIG_REG) = SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | - SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | + SE(SE_SPARE_REG) = SE_INPUT_NONCE_LE; + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_ENCRYPT) | + SE_CRYPTO_XOR_POS(XOR_BOTTOM) | SE_CRYPTO_INPUT_SEL(INPUT_LNR_CTR) | SE_CRYPTO_CTR_CNTN(1); - _se_aes_ctr_set(ctr); + + _se_aes_counter_set(ctr); u32 src_size_aligned = src_size & 0xFFFFFFF0; u32 src_size_delta = src_size & 0xF; if (src_size_aligned) { - SE(SE_CRYPTO_BLOCK_COUNT_REG) = (src_size >> 4) - 1; + SE(SE_CRYPTO_LAST_BLOCK_REG) = (src_size >> 4) - 1; if (!_se_execute_oneshot(SE_OP_START, dst, dst_size, src, src_size_aligned)) return 0; } @@ -384,7 +384,7 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s return 1; } -int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize) +int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, void *dst, void *src, u32 secsize) { int res = 0; u32 tmp[SE_AES_BLOCK_SIZE / sizeof(u32)]; @@ -393,7 +393,7 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst u8 *psrc = (u8 *)src; // Generate tweak. - for (int i = 0xF; i >= 0; i--) + for (int i = SE_AES_BLOCK_SIZE - 1; i >= 0; i--) { tweak[i] = sec & 0xFF; sec >>= 8; @@ -410,7 +410,7 @@ int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst goto out; for (u32 j = 0; j < SE_AES_BLOCK_SIZE; j++) pdst[j] = pdst[j] ^ tweak[j]; - _gf256_mul_x(tweak); + _se_ls_1bit(tweak); psrc += SE_AES_BLOCK_SIZE; pdst += SE_AES_BLOCK_SIZE; } @@ -421,7 +421,7 @@ out: return res; } -int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size) +int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size) { u32 *pdst = (u32 *)dst; u32 *psrc = (u32 *)src; @@ -429,7 +429,7 @@ int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tw if (regen_tweak) { - for (int i = 0xF; i >= 0; i--) + for (int i = SE_AES_BLOCK_SIZE - 1; i >= 0; i--) { tweak[i] = sec & 0xFF; sec >>= 8; @@ -438,9 +438,9 @@ int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tw return 0; } - // tweak_exp allows using a saved tweak to reduce _gf256_mul_x_le calls. + // tweak_exp allows using a saved tweak to reduce _se_ls_1bit_le calls. for (u32 i = 0; i < (tweak_exp << 5); i++) - _gf256_mul_x_le(tweak); + _se_ls_1bit_le(tweak); u8 orig_tweak[SE_KEY_128_SIZE] __attribute__((aligned(4))); memcpy(orig_tweak, tweak, SE_KEY_128_SIZE); @@ -448,12 +448,12 @@ int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tw // We are assuming a 16 sector aligned size in this implementation. for (u32 i = 0; i < (sec_size >> 4); i++) { - for (u32 j = 0; j < 4; j++) + for (u32 j = 0; j < (SE_AES_BLOCK_SIZE / sizeof(u32)); j++) pdst[j] = psrc[j] ^ ptweak[j]; - _gf256_mul_x_le(tweak); - psrc += 4; - pdst += 4; + _se_ls_1bit_le(tweak); + psrc += sizeof(u32); + pdst += sizeof(u32); } if (!se_aes_crypt_ecb(crypt_ks, enc, dst, sec_size, dst, sec_size)) @@ -463,17 +463,17 @@ int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tw ptweak = (u32 *)orig_tweak; for (u32 i = 0; i < (sec_size >> 4); i++) { - for (u32 j = 0; j < 4; j++) + for (u32 j = 0; j < (SE_AES_BLOCK_SIZE / sizeof(u32)); j++) pdst[j] = pdst[j] ^ ptweak[j]; - _gf256_mul_x_le(orig_tweak); - pdst += 4; + _se_ls_1bit_le(orig_tweak); + pdst += sizeof(u32); } return 1; } -int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs) +int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs) { u8 *pdst = (u8 *)dst; u8 *psrc = (u8 *)src; @@ -487,8 +487,6 @@ int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, vo static void se_calc_sha256_get_hash(void *hash, u32 *msg_left) { - u32 hash32[SE_SHA_256_SIZE / 4]; - // Backup message left. if (msg_left) { @@ -497,8 +495,9 @@ static void se_calc_sha256_get_hash(void *hash, u32 *msg_left) } // Copy output hash. - for (u32 i = 0; i < (SE_SHA_256_SIZE / 4); i++) - hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + (i * 4))); + u32 hash32[SE_SHA_256_SIZE / sizeof(u32)]; + for (u32 i = 0; i < (SE_SHA_256_SIZE / sizeof(u32)); i++) + hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG + sizeof(u32) * i)); memcpy(hash, hash32, SE_SHA_256_SIZE); } @@ -525,7 +524,7 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 // Setup config for SHA256. SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG); SE(SE_SHA_CONFIG_REG) = sha_cfg; - SE(SE_CRYPTO_BLOCK_COUNT_REG) = 1 - 1; + SE(SE_CRYPTO_LAST_BLOCK_REG) = 1 - 1; // Set total size to current buffer size if empty. if (!total_size) @@ -581,15 +580,14 @@ int se_calc_sha256_finalize(void *hash, u32 *msg_left) int se_gen_prng128(void *dst) { - // Setup config for X931 PRNG. - SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY); - SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_HASH(HASH_DISABLE) | SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); - SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_NORMAL); - //SE(SE_RNG_SRC_CONFIG_REG) = - // SE_RNG_SRC_CONFIG_ENTR_SRC(RO_ENTR_ENABLE) | SE_RNG_SRC_CONFIG_ENTR_SRC_LOCK(RO_ENTR_LOCK_ENABLE); + // Setup config for SP 800-90 PRNG. + SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_RNG) | SE_CONFIG_DST(DST_MEMORY); + SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_XOR_POS(XOR_BYPASS) | SE_CRYPTO_INPUT_SEL(INPUT_RANDOM); + SE(SE_RNG_CONFIG_REG) = SE_RNG_CONFIG_SRC(SRC_ENTROPY) | SE_RNG_CONFIG_MODE(MODE_NORMAL); + //SE(SE_RNG_SRC_CONFIG_REG) |= SE_RNG_SRC_CONFIG_ENTR_SRC(RO_ENTR_ENABLE); // DRBG. Depends on ENTROPY clock. SE(SE_RNG_RESEED_INTERVAL_REG) = 1; - SE(SE_CRYPTO_BLOCK_COUNT_REG) = (16 >> 4) - 1; + SE(SE_CRYPTO_LAST_BLOCK_REG) = (16 >> 4) - 1; // Trigger the operation. return _se_execute_oneshot(SE_OP_START, dst, 16, NULL, 0); @@ -652,25 +650,25 @@ void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize) se_aes_key_clear(3); } -int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size) +int se_aes_cmac_128(u32 ks, void *hash, const void *src, u32 size) { int res = 0; u32 tmp1[SE_KEY_128_SIZE / sizeof(u32)] = {0}; u32 tmp2[SE_AES_BLOCK_SIZE / sizeof(u32)] = {0}; - u8 *key = (u8 *)tmp1; + u8 *subkey = (u8 *)tmp1; u8 *last_block = (u8 *)tmp2; + // Generate sub key (CBC with zeroed IV, basically ECB). se_aes_iv_clear(ks); se_aes_iv_updated_clear(ks); - - // Generate sub key - if (!se_aes_crypt_hash(ks, ENCRYPT, key, SE_KEY_128_SIZE, key, SE_KEY_128_SIZE)) + if (!se_aes_crypt_hash(ks, ENCRYPT, subkey, SE_KEY_128_SIZE, subkey, SE_KEY_128_SIZE)) goto out; - _gf256_mul_x(key); - if (src_size & 0xF) - _gf256_mul_x(key); + // Generate K1 subkey. + _se_ls_1bit(subkey); + if (size & 0xF) + _se_ls_1bit(subkey); // Convert to K2. SE(SE_CONFIG_REG) = SE_CONFIG_ENC_MODE(MODE_KEY128) | SE_CONFIG_ENC_ALG(ALG_AES_ENC) | SE_CONFIG_DST(DST_HASHREG); SE(SE_CRYPTO_CONFIG_REG) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_INPUT_SEL(INPUT_MEMORY) | @@ -679,34 +677,35 @@ int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size) se_aes_iv_clear(ks); se_aes_iv_updated_clear(ks); - u32 num_blocks = (src_size + 0xf) >> 4; + u32 num_blocks = (size + 0xF) >> 4; if (num_blocks > 1) { - SE(SE_CRYPTO_BLOCK_COUNT_REG) = num_blocks - 2; - if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, src_size)) + SE(SE_CRYPTO_LAST_BLOCK_REG) = num_blocks - 2; + if (!_se_execute_oneshot(SE_OP_START, NULL, 0, src, size)) goto out; SE(SE_CRYPTO_CONFIG_REG) |= SE_CRYPTO_IV_SEL(IV_UPDATED); } - if (src_size & 0xf) + if (size & 0xF) { - memcpy(last_block, src + (src_size & ~0xf), src_size & 0xf); - last_block[src_size & 0xf] = 0x80; + memcpy(last_block, src + (size & ~0xF), size & 0xF); + last_block[size & 0xF] = 0x80; } - else if (src_size >= SE_AES_BLOCK_SIZE) + else if (size >= SE_AES_BLOCK_SIZE) { - memcpy(last_block, src + src_size - SE_AES_BLOCK_SIZE, SE_AES_BLOCK_SIZE); + memcpy(last_block, src + size - SE_AES_BLOCK_SIZE, SE_AES_BLOCK_SIZE); } for (u32 i = 0; i < SE_KEY_128_SIZE; i++) - last_block[i] ^= key[i]; + last_block[i] ^= subkey[i]; + + SE(SE_CRYPTO_LAST_BLOCK_REG) = 0; - SE(SE_CRYPTO_BLOCK_COUNT_REG) = 0; res = _se_execute_oneshot(SE_OP_START, NULL, 0, last_block, SE_AES_BLOCK_SIZE); - u32 *dst32 = (u32 *)dst; - for (u32 i = 0; i < (SE_KEY_128_SIZE / 4); i++) - dst32[i] = SE(SE_HASH_RESULT_REG + (i * 4)); + u32 *hash32 = (u32 *)hash; + for (u32 i = 0; i < (SE_AES_CMAC_DIGEST_SIZE / sizeof(u32)); i++) + hash32[i] = SE(SE_HASH_RESULT_REG + sizeof(u32) * i); out: return res; diff --git a/bdk/sec/se.h b/bdk/sec/se.h index 36b057b4..9652931b 100644 --- a/bdk/sec/se.h +++ b/bdk/sec/se.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2019-2022 CTCaer + * Copyright (c) 2019-2026 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -24,26 +24,31 @@ void se_rsa_acc_ctrl(u32 rs, u32 flags); void se_key_acc_ctrl(u32 ks, u32 flags); u32 se_key_acc_ctrl_get(u32 ks); -void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize); + +/*! AES Key Management Functions */ void se_aes_key_set(u32 ks, const void *key, u32 size); void se_aes_iv_set(u32 ks, const void *iv); void se_aes_key_get(u32 ks, void *key, u32 size); void se_aes_key_clear(u32 ks); void se_aes_iv_clear(u32 ks); void se_aes_iv_updated_clear(u32 ks); -int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input); -int se_aes_crypt_hash(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); -int se_aes_crypt_cbc(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); -int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); -int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src); -int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize); -int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size); -int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, u32 enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs); +int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *seed); +void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize); +/*! Encryption Functions */ +int se_aes_crypt_cbc(u32 ks, int enc, void *dst, u32 dst_size, const void *src, u32 src_size); +int se_aes_crypt_ecb(u32 ks, int enc, void *dst, u32 dst_size, const void *src, u32 src_size); +int se_aes_crypt_block_ecb(u32 ks, int enc, void *dst, const void *src); +int se_aes_xts_crypt_sec(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, void *dst, void *src, u32 secsize); +int se_aes_xts_crypt_sec_nx(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, u8 *tweak, bool regen_tweak, u32 tweak_exp, void *dst, void *src, u32 sec_size); +int se_aes_xts_crypt(u32 tweak_ks, u32 crypt_ks, int enc, u64 sec, void *dst, void *src, u32 secsize, u32 num_secs); +/*! Hashing Functions */ +int se_aes_crypt_hash(u32 ks, int enc, void *dst, u32 dst_size, const void *src, u32 src_size); int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr); int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot); int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size); int se_calc_sha256_finalize(void *hash, u32 *msg_left); +int se_aes_cmac_128(u32 ks, void *hash, const void *src, u32 size); +/*! Random Functions */ int se_gen_prng128(void *dst); -int se_aes_cmac_128(u32 ks, void *dst, const void *src, u32 src_size); #endif diff --git a/bdk/sec/se_t210.h b/bdk/sec/se_t210.h index 317c4fa6..4b638aea 100644 --- a/bdk/sec/se_t210.h +++ b/bdk/sec/se_t210.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2021 CTCaer + * Copyright (c) 2018-2026 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -26,7 +26,6 @@ #define SE_AES_KEYSLOT_COUNT 16 #define SE_RSA_KEYSLOT_COUNT 2 -#define SE_MAX_LAST_BLOCK_SIZE 0xFFFFF #define SE_AES_BLOCK_SIZE 16 #define SE_AES_IV_SIZE 16 @@ -39,9 +38,10 @@ #define SE_SHA_256_SIZE 32 #define SE_SHA_384_SIZE 48 #define SE_SHA_512_SIZE 64 -#define SE_RNG_IV_SIZE 16 -#define SE_RNG_DT_SIZE 16 -#define SE_RNG_KEY_SIZE 16 +#define SE_RNG_BLOCK_SIZE 16 +#define SE_RNG_IV_SIZE 16 +#define SE_RNG_DT_SIZE 16 +#define SE_RNG_KEY_SIZE 16 #define SE_RNG_SEED_SIZE (SE_RNG_IV_SIZE + SE_RNG_KEY_SIZE + SE_RNG_DT_SIZE) #define SE_AES_CMAC_DIGEST_SIZE 16 @@ -50,6 +50,11 @@ #define SE_RSA1536_DIGEST_SIZE 192 #define SE_RSA2048_DIGEST_SIZE 256 +#define SE_SHA2_MIN_BLOCK_SIZE 64 +#define SE_SHA2_MAX_BLOCK_SIZE 128 + +#define SE_LL_MAX_SIZE ALIGN_DOWN(0xFFFFFF, SE_SHA2_MAX_BLOCK_SIZE) + #define DECRYPT 0 #define ENCRYPT 1 @@ -211,7 +216,7 @@ #define SE_CRYPTO_LINEAR_CTR_REG 0x308 #define SE_CRYPTO_LINEAR_CTR_REG_COUNT 4 -#define SE_CRYPTO_BLOCK_COUNT_REG 0x318 +#define SE_CRYPTO_LAST_BLOCK_REG 0x318 #define SE_CRYPTO_KEYTABLE_ADDR_REG 0x31C #define SE_KEYTABLE_PKT(x) ((x) << 0) @@ -321,8 +326,6 @@ #define SE_CLK_OVR_ON BIT(2) #define SE_SPARE_REG 0x80C -#define SE_ERRATA_FIX_DISABLE 0 -#define SE_ERRATA_FIX_ENABLE 1 -#define SE_ECO(x) ((x) << 0) +#define SE_INPUT_NONCE_LE BIT(0) #endif