Skip to content

Commit c7d90ec

Browse files
committedNov 3, 2022
Further improve readability
1 parent cc4f8bf commit c7d90ec

File tree

8 files changed

+195
-207
lines changed

8 files changed

+195
-207
lines changed
 

‎bdk/sec/se.c

-70
Original file line numberDiff line numberDiff line change
@@ -718,76 +718,6 @@ out:;
718718
return res;
719719
}
720720

721-
// _mgf1_xor() and rsa_oaep_decode were derived from Atmosphère
722-
static void _mgf1_xor(void *masked, u32 masked_size, const void *seed, u32 seed_size)
723-
{
724-
u8 cur_hash[0x20] __attribute__((aligned(4)));
725-
u8 hash_buf[0xe4] __attribute__((aligned(4)));
726-
727-
u32 hash_buf_size = seed_size + 4;
728-
memcpy(hash_buf, seed, seed_size);
729-
u32 round_num = 0;
730-
731-
u8 *p_out = (u8 *)masked;
732-
733-
while (masked_size) {
734-
u32 cur_size = MIN(masked_size, 0x20);
735-
736-
for (u32 i = 0; i < 4; i++)
737-
hash_buf[seed_size + 3 - i] = (round_num >> (8 * i)) & 0xff;
738-
round_num++;
739-
740-
se_calc_sha256_oneshot(cur_hash, hash_buf, hash_buf_size);
741-
742-
for (unsigned int i = 0; i < cur_size; i++) {
743-
*p_out ^= cur_hash[i];
744-
p_out++;
745-
}
746-
747-
masked_size -= cur_size;
748-
}
749-
}
750-
751-
u32 se_rsa_oaep_decode(void *dst, u32 dst_size, const void *label_digest, u32 label_digest_size, u8 *buf, u32 buf_size)
752-
{
753-
if (dst_size <= 0 || buf_size < 0x43 || label_digest_size != 0x20)
754-
return 0;
755-
756-
bool is_valid = buf[0] == 0;
757-
758-
u32 db_len = buf_size - 0x21;
759-
u8 *seed = buf + 1;
760-
u8 *db = seed + 0x20;
761-
_mgf1_xor(seed, 0x20, db, db_len);
762-
_mgf1_xor(db, db_len, seed, 0x20);
763-
764-
is_valid &= memcmp(label_digest, db, 0x20) ? 0 : 1;
765-
766-
db += 0x20;
767-
db_len -= 0x20;
768-
769-
int msg_ofs = 0;
770-
int looking_for_one = 1;
771-
int invalid_db_padding = 0;
772-
int is_zero;
773-
int is_one;
774-
for (int i = 0; i < db_len; )
775-
{
776-
is_zero = (db[i] == 0);
777-
is_one = (db[i] == 1);
778-
msg_ofs += (looking_for_one & is_one) * (++i);
779-
looking_for_one &= ~is_one;
780-
invalid_db_padding |= (looking_for_one & ~is_zero);
781-
}
782-
783-
is_valid &= (invalid_db_padding == 0);
784-
785-
const u32 msg_size = MIN(dst_size, is_valid * (db_len - msg_ofs));
786-
memcpy(dst, db + msg_ofs, msg_size);
787-
788-
return msg_size;
789-
}
790-
791721
void se_get_aes_keys(u8 *buf, u8 *keys, u32 keysize)
792722
{
793723
u8 *aligned_buf = (u8 *)ALIGN((u32)buf, 0x40);

‎bdk/sec/se.h

-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,5 @@ int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64
4949
int se_calc_sha256_oneshot(void *hash, const void *src, u32 src_size);
5050
int se_calc_sha256_finalize(void *hash, u32 *msg_left);
5151
int se_calc_hmac_sha256(void *dst, const void *src, u32 src_size, const void *key, u32 key_size);
52-
u32 se_rsa_oaep_decode(void *dst, u32 dst_size, const void *label_digest, u32 label_digest_size, u8 *buf, u32 buf_size);
5352

5453
#endif

‎bdk/utils/util.c

-14
Original file line numberDiff line numberDiff line change
@@ -230,17 +230,3 @@ void power_set_state_ex(void *param)
230230
power_state_t *state = (power_state_t *)param;
231231
power_set_state(*state);
232232
}
233-
234-
u32 read_le_u32(const void *buffer, u32 offset) {
235-
return (*(u8*)(buffer + offset + 0) ) |
236-
(*(u8*)(buffer + offset + 1) << 0x08) |
237-
(*(u8*)(buffer + offset + 2) << 0x10) |
238-
(*(u8*)(buffer + offset + 3) << 0x18);
239-
}
240-
241-
u32 read_be_u32(const void *buffer, u32 offset) {
242-
return (*(u8*)(buffer + offset + 3) ) |
243-
(*(u8*)(buffer + offset + 2) << 0x08) |
244-
(*(u8*)(buffer + offset + 1) << 0x10) |
245-
(*(u8*)(buffer + offset + 0) << 0x18);
246-
}

‎bdk/utils/util.h

-3
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,4 @@ void panic(u32 val);
9696
void power_set_state(power_state_t state);
9797
void power_set_state_ex(void *param);
9898

99-
u32 read_le_u32(const void *buffer, u32 offset);
100-
u32 read_be_u32(const void *buffer, u32 offset);
101-
10299
#endif

‎source/keys/crypto.c

+81-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2022 shchmue
3+
* Copyright (c) 2018 Atmosphère-NX
34
*
45
* This program is free software; you can redistribute it and/or modify it
56
* under the terms and conditions of the GNU General Public License,
@@ -27,6 +28,15 @@
2728

2829
extern hekate_config h_cfg;
2930

31+
bool check_keyslot_access() {
32+
u8 test_data[SE_KEY_128_SIZE] = {0};
33+
const u8 test_ciphertext[SE_KEY_128_SIZE] = {0};
34+
se_aes_key_set(KS_AES_ECB, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", SE_KEY_128_SIZE);
35+
se_aes_crypt_block_ecb(KS_AES_ECB, DECRYPT, test_data, test_ciphertext);
36+
37+
return memcmp(test_data, "\x7b\x1d\x29\xa1\x6c\xf8\xcc\xab\x84\xf0\xb8\xa5\x98\xe4\x2f\xa6", SE_KEY_128_SIZE) == 0;
38+
}
39+
3040
bool test_rsa_keypair(const void *public_exponent, const void *private_exponent, const void *modulus) {
3141
u32 plaintext[SE_RSA2048_DIGEST_SIZE / 4] = {0},
3242
ciphertext[SE_RSA2048_DIGEST_SIZE / 4] = {0},
@@ -46,13 +56,82 @@ bool test_rsa_keypair(const void *public_exponent, const void *private_exponent,
4656
bool test_eticket_rsa_keypair(const rsa_keypair_t *keypair) {
4757
// Unlike the SSL RSA key, we don't need to check the gmac - we can just verify the public exponent
4858
// and test the keypair since we have the modulus
49-
if ((read_be_u32(keypair->public_exponent, 0) != RSA_PUBLIC_EXPONENT) ||
50-
(!test_rsa_keypair(keypair->public_exponent, keypair->private_exponent, keypair->modulus))) {
59+
if ((byte_swap_32(keypair->public_exponent) != RSA_PUBLIC_EXPONENT) ||
60+
(!test_rsa_keypair(&keypair->public_exponent, keypair->private_exponent, keypair->modulus))
61+
) {
5162
return false;
5263
}
5364
return true;
5465
}
5566

67+
// _mgf1_xor() and rsa_oaep_decode were derived from Atmosphère
68+
static void _mgf1_xor(void *masked, u32 masked_size, const void *seed, u32 seed_size)
69+
{
70+
u8 cur_hash[0x20] __attribute__((aligned(4)));
71+
u8 hash_buf[0xe4] __attribute__((aligned(4)));
72+
73+
u32 hash_buf_size = seed_size + 4;
74+
memcpy(hash_buf, seed, seed_size);
75+
u32 round_num = 0;
76+
77+
u8 *p_out = (u8 *)masked;
78+
79+
while (masked_size) {
80+
u32 cur_size = MIN(masked_size, 0x20);
81+
82+
for (u32 i = 0; i < 4; i++)
83+
hash_buf[seed_size + 3 - i] = (round_num >> (8 * i)) & 0xff;
84+
round_num++;
85+
86+
se_calc_sha256_oneshot(cur_hash, hash_buf, hash_buf_size);
87+
88+
for (unsigned int i = 0; i < cur_size; i++) {
89+
*p_out ^= cur_hash[i];
90+
p_out++;
91+
}
92+
93+
masked_size -= cur_size;
94+
}
95+
}
96+
97+
u32 rsa_oaep_decode(void *dst, u32 dst_size, const void *label_digest, u32 label_digest_size, u8 *buf, u32 buf_size) {
98+
if (dst_size <= 0 || buf_size < 0x43 || label_digest_size != 0x20)
99+
return 0;
100+
101+
bool is_valid = buf[0] == 0;
102+
103+
u32 db_len = buf_size - 0x21;
104+
u8 *seed = buf + 1;
105+
u8 *db = seed + 0x20;
106+
_mgf1_xor(seed, 0x20, db, db_len);
107+
_mgf1_xor(db, db_len, seed, 0x20);
108+
109+
is_valid &= memcmp(label_digest, db, 0x20) ? 0 : 1;
110+
111+
db += 0x20;
112+
db_len -= 0x20;
113+
114+
int msg_ofs = 0;
115+
int looking_for_one = 1;
116+
int invalid_db_padding = 0;
117+
int is_zero;
118+
int is_one;
119+
for (int i = 0; i < db_len; ) {
120+
is_zero = (db[i] == 0);
121+
is_one = (db[i] == 1);
122+
msg_ofs += (looking_for_one & is_one) * (++i);
123+
looking_for_one &= ~is_one;
124+
invalid_db_padding |= (looking_for_one & ~is_zero);
125+
}
126+
127+
is_valid &= (invalid_db_padding == 0);
128+
129+
const u32 msg_size = MIN(dst_size, is_valid * (db_len - msg_ofs));
130+
memcpy(dst, db + msg_ofs, msg_size);
131+
132+
return msg_size;
133+
}
134+
56135
// Equivalent to spl::GenerateAesKek
57136
void generate_aes_kek(u32 ks, key_storage_t *keys, void *out_kek, const void *kek_source, u32 generation, u32 option) {
58137
bool device_unique = GET_IS_DEVICE_UNIQUE(option);

‎source/keys/crypto.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,12 @@ static const u8 secure_data_tweaks[1][0x10] __attribute__((aligned(4))) = {
127127
#define SSL_RSA_KEY_SIZE (SE_AES_IV_SIZE + SE_RSA2048_DIGEST_SIZE)
128128
#define ETICKET_RSA_KEYPAIR_SIZE (SE_AES_IV_SIZE + SE_RSA2048_DIGEST_SIZE * 2 + SE_KEY_128_SIZE)
129129

130+
#define TICKET_SIG_TYPE_RSA2048_SHA256 0x10004
131+
130132
typedef struct {
131133
u8 private_exponent[SE_RSA2048_DIGEST_SIZE];
132134
u8 modulus[SE_RSA2048_DIGEST_SIZE];
133-
u8 public_exponent[4];
135+
u32 public_exponent;
134136
u8 reserved[0xC];
135137
} rsa_keypair_t;
136138

@@ -199,8 +201,11 @@ typedef enum {
199201
#define GET_SEAL_KEY_INDEX(x) (((x) >> 5) & 7)
200202
#define GET_IS_DEVICE_UNIQUE(x) ((x) & 1)
201203

204+
bool check_keyslot_access();
205+
202206
bool test_rsa_keypair(const void *public_exponent, const void *private_exponent, const void *modulus);
203207
bool test_eticket_rsa_keypair(const rsa_keypair_t *keypair);
208+
u32 rsa_oaep_decode(void *dst, u32 dst_size, const void *label_digest, u32 label_digest_size, u8 *buf, u32 buf_size);
204209

205210
// Equivalent to spl::GenerateAesKek
206211
void generate_aes_kek(u32 ks, key_storage_t *keys, void *out_kek, const void *kek_source, u32 generation, u32 option);

‎source/keys/keys.c

+107-115
Large diffs are not rendered by default.

‎source/keys/keys.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
// only tickets of type Rsa2048Sha256 are expected
2727
typedef struct {
28-
u32 signature_type; // always 0x10004
28+
u32 signature_type; // always 0x10004
2929
u8 signature[SE_RSA2048_DIGEST_SIZE];
3030
u8 sig_padding[0x3C];
3131
char issuer[0x40];

0 commit comments

Comments
 (0)
Please sign in to comment.