summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar german772022-09-07 01:03:02 -0500
committerGravatar german772022-09-07 09:49:43 -0500
commit063b23cc58b1e7367f9e530e752ab56fe1f56532 (patch)
tree6d227dca418bb26529762f2ce038c0776a569892 /src
parentcore: nfp: Workaround for lack of multiple nfp interfaces (diff)
downloadyuzu-063b23cc58b1e7367f9e530e752ab56fe1f56532.tar.gz
yuzu-063b23cc58b1e7367f9e530e752ab56fe1f56532.tar.xz
yuzu-063b23cc58b1e7367f9e530e752ab56fe1f56532.zip
core: nfp: Remove magic numbers
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/nfp/amiibo_crypto.cpp171
-rw-r--r--src/core/hle/service/nfp/amiibo_crypto.h29
-rw-r--r--src/core/hle/service/nfp/amiibo_types.h8
3 files changed, 103 insertions, 105 deletions
diff --git a/src/core/hle/service/nfp/amiibo_crypto.cpp b/src/core/hle/service/nfp/amiibo_crypto.cpp
index d9d0c8f62..31dd3a307 100644
--- a/src/core/hle/service/nfp/amiibo_crypto.cpp
+++ b/src/core/hle/service/nfp/amiibo_crypto.cpp
@@ -70,10 +70,10 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) {
70NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) { 70NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
71 NTAG215File encoded_data{}; 71 NTAG215File encoded_data{};
72 72
73 memcpy(encoded_data.uuid2.data(), nfc_data.uuid.data() + 0x8, 2); 73 memcpy(encoded_data.uuid2.data(), nfc_data.uuid.data() + 0x8, sizeof(encoded_data.uuid2));
74 encoded_data.static_lock = nfc_data.static_lock; 74 encoded_data.static_lock = nfc_data.static_lock;
75 encoded_data.compability_container = nfc_data.compability_container; 75 encoded_data.compability_container = nfc_data.compability_container;
76 encoded_data.unfixed_hash = nfc_data.user_memory.unfixed_hash; 76 encoded_data.hmac_data = nfc_data.user_memory.hmac_data;
77 encoded_data.constant_value = nfc_data.user_memory.constant_value; 77 encoded_data.constant_value = nfc_data.user_memory.constant_value;
78 encoded_data.write_counter = nfc_data.user_memory.write_counter; 78 encoded_data.write_counter = nfc_data.user_memory.write_counter;
79 encoded_data.settings = nfc_data.user_memory.settings; 79 encoded_data.settings = nfc_data.user_memory.settings;
@@ -84,8 +84,8 @@ NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
84 encoded_data.unknown = nfc_data.user_memory.unknown; 84 encoded_data.unknown = nfc_data.user_memory.unknown;
85 encoded_data.hash = nfc_data.user_memory.hash; 85 encoded_data.hash = nfc_data.user_memory.hash;
86 encoded_data.application_area = nfc_data.user_memory.application_area; 86 encoded_data.application_area = nfc_data.user_memory.application_area;
87 encoded_data.locked_hash = nfc_data.user_memory.locked_hash; 87 encoded_data.hmac_tag = nfc_data.user_memory.hmac_tag;
88 memcpy(encoded_data.uuid.data(), nfc_data.uuid.data(), 8); 88 memcpy(encoded_data.uuid.data(), nfc_data.uuid.data(), sizeof(encoded_data.uuid));
89 encoded_data.model_info = nfc_data.user_memory.model_info; 89 encoded_data.model_info = nfc_data.user_memory.model_info;
90 encoded_data.keygen_salt = nfc_data.user_memory.keygen_salt; 90 encoded_data.keygen_salt = nfc_data.user_memory.keygen_salt;
91 encoded_data.dynamic_lock = nfc_data.dynamic_lock; 91 encoded_data.dynamic_lock = nfc_data.dynamic_lock;
@@ -99,11 +99,11 @@ NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
99EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) { 99EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) {
100 EncryptedNTAG215File nfc_data{}; 100 EncryptedNTAG215File nfc_data{};
101 101
102 memcpy(nfc_data.uuid.data() + 0x8, encoded_data.uuid2.data(), 2); 102 memcpy(nfc_data.uuid.data() + 0x8, encoded_data.uuid2.data(), sizeof(encoded_data.uuid2));
103 memcpy(nfc_data.uuid.data(), encoded_data.uuid.data(), 8); 103 memcpy(nfc_data.uuid.data(), encoded_data.uuid.data(), sizeof(encoded_data.uuid));
104 nfc_data.static_lock = encoded_data.static_lock; 104 nfc_data.static_lock = encoded_data.static_lock;
105 nfc_data.compability_container = encoded_data.compability_container; 105 nfc_data.compability_container = encoded_data.compability_container;
106 nfc_data.user_memory.unfixed_hash = encoded_data.unfixed_hash; 106 nfc_data.user_memory.hmac_data = encoded_data.hmac_data;
107 nfc_data.user_memory.constant_value = encoded_data.constant_value; 107 nfc_data.user_memory.constant_value = encoded_data.constant_value;
108 nfc_data.user_memory.write_counter = encoded_data.write_counter; 108 nfc_data.user_memory.write_counter = encoded_data.write_counter;
109 nfc_data.user_memory.settings = encoded_data.settings; 109 nfc_data.user_memory.settings = encoded_data.settings;
@@ -114,7 +114,7 @@ EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) {
114 nfc_data.user_memory.unknown = encoded_data.unknown; 114 nfc_data.user_memory.unknown = encoded_data.unknown;
115 nfc_data.user_memory.hash = encoded_data.hash; 115 nfc_data.user_memory.hash = encoded_data.hash;
116 nfc_data.user_memory.application_area = encoded_data.application_area; 116 nfc_data.user_memory.application_area = encoded_data.application_area;
117 nfc_data.user_memory.locked_hash = encoded_data.locked_hash; 117 nfc_data.user_memory.hmac_tag = encoded_data.hmac_tag;
118 nfc_data.user_memory.model_info = encoded_data.model_info; 118 nfc_data.user_memory.model_info = encoded_data.model_info;
119 nfc_data.user_memory.keygen_salt = encoded_data.keygen_salt; 119 nfc_data.user_memory.keygen_salt = encoded_data.keygen_salt;
120 nfc_data.dynamic_lock = encoded_data.dynamic_lock; 120 nfc_data.dynamic_lock = encoded_data.dynamic_lock;
@@ -136,60 +136,53 @@ u32 GetTagPassword(const TagUuid& uuid) {
136 136
137HashSeed GetSeed(const NTAG215File& data) { 137HashSeed GetSeed(const NTAG215File& data) {
138 HashSeed seed{ 138 HashSeed seed{
139 .data = 139 .magic = data.write_counter,
140 { 140 .padding = {},
141 .magic = data.write_counter, 141 .uuid1 = {},
142 .padding = {}, 142 .uuid2 = {},
143 .uuid1 = {}, 143 .keygen_salt = data.keygen_salt,
144 .uuid2 = {},
145 .keygen_salt = data.keygen_salt,
146 },
147 }; 144 };
148 145
149 // Copy the first 8 bytes of uuid 146 // Copy the first 8 bytes of uuid
150 memcpy(seed.data.uuid1.data(), data.uuid.data(), sizeof(seed.data.uuid1)); 147 memcpy(seed.uuid1.data(), data.uuid.data(), sizeof(seed.uuid1));
151 memcpy(seed.data.uuid2.data(), data.uuid.data(), sizeof(seed.data.uuid2)); 148 memcpy(seed.uuid2.data(), data.uuid.data(), sizeof(seed.uuid2));
152 149
153 return seed; 150 return seed;
154} 151}
155 152
156void PreGenerateKey(const InternalKey& key, const HashSeed& seed, u8* output, 153std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed) {
157 std::size_t& outputLen) { 154 const std::size_t seedPart1Len = sizeof(key.magic_bytes) - key.magic_length;
158 std::size_t index = 0; 155 const std::size_t string_size = key.type_string.size();
156 std::vector<u8> output(string_size + seedPart1Len);
159 157
160 // Copy whole type string 158 // Copy whole type string
161 memccpy(output + index, key.type_string.data(), '\0', key.type_string.size()); 159 memccpy(output.data(), key.type_string.data(), '\0', string_size);
162 index += key.type_string.size();
163 160
164 // Append (16 - magic_length) from the input seed 161 // Append (16 - magic_length) from the input seed
165 std::size_t seedPart1Len = 16 - key.magic_length; 162 memcpy(output.data() + string_size, &seed, seedPart1Len);
166 memcpy(output + index, &seed, seedPart1Len);
167 index += seedPart1Len;
168 163
169 // Append all bytes from magicBytes 164 // Append all bytes from magicBytes
170 memcpy(output + index, &key.magic_bytes, key.magic_length); 165 output.insert(output.end(), key.magic_bytes.begin(),
171 index += key.magic_length; 166 key.magic_bytes.begin() + key.magic_length);
172 167
173 // Seed 16 bytes at +0x10 168 output.insert(output.end(), seed.uuid1.begin(), seed.uuid1.end());
174 memcpy(output + index, &seed.raw[0x10], 16); 169 output.insert(output.end(), seed.uuid2.begin(), seed.uuid2.end());
175 index += 16;
176 170
177 // 32 bytes at +0x20 from input seed xored with xor pad 171 for (std::size_t i = 0; i < sizeof(seed.keygen_salt); i++) {
178 for (std::size_t i = 0; i < 32; i++) 172 output.emplace_back(static_cast<u8>(seed.keygen_salt[i] ^ key.xor_pad[i]));
179 output[index + i] = seed.raw[i + 32] ^ key.xor_pad[i]; 173 }
180 index += 32;
181 174
182 outputLen = index; 175 return output;
183} 176}
184 177
185void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key, 178void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key,
186 const u8* seed, std::size_t seed_size) { 179 const std::vector<u8>& seed) {
187 180
188 // Initialize context 181 // Initialize context
189 ctx.used = false; 182 ctx.used = false;
190 ctx.counter = 0; 183 ctx.counter = 0;
191 ctx.buffer_size = sizeof(ctx.counter) + seed_size; 184 ctx.buffer_size = sizeof(ctx.counter) + seed.size();
192 memcpy(ctx.buffer.data() + sizeof(u16), seed, seed_size); 185 memcpy(ctx.buffer.data() + sizeof(u16), seed.data(), seed.size());
193 186
194 // Initialize HMAC context 187 // Initialize HMAC context
195 mbedtls_md_init(&hmac_ctx); 188 mbedtls_md_init(&hmac_ctx);
@@ -217,18 +210,15 @@ void CryptoStep(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, DrgbOutput& outp
217} 210}
218 211
219DerivedKeys GenerateKey(const InternalKey& key, const NTAG215File& data) { 212DerivedKeys GenerateKey(const InternalKey& key, const NTAG215File& data) {
220 constexpr std::size_t OUTPUT_SIZE = 512;
221 const auto seed = GetSeed(data); 213 const auto seed = GetSeed(data);
222 214
223 // Generate internal seed 215 // Generate internal seed
224 u8 internal_key[OUTPUT_SIZE]; 216 const std::vector<u8> internal_key = GenerateInternalKey(key, seed);
225 std::size_t internal_key_lenght = 0;
226 PreGenerateKey(key, seed, internal_key, internal_key_lenght);
227 217
228 // Initialize context 218 // Initialize context
229 CryptoCtx ctx{}; 219 CryptoCtx ctx{};
230 mbedtls_md_context_t hmac_ctx; 220 mbedtls_md_context_t hmac_ctx;
231 CryptoInit(ctx, hmac_ctx, key.hmac_key, internal_key, internal_key_lenght); 221 CryptoInit(ctx, hmac_ctx, key.hmac_key, internal_key);
232 222
233 // Generate derived keys 223 // Generate derived keys
234 DerivedKeys derived_keys{}; 224 DerivedKeys derived_keys{};
@@ -246,27 +236,34 @@ DerivedKeys GenerateKey(const InternalKey& key, const NTAG215File& data) {
246void Cipher(const DerivedKeys& keys, const NTAG215File& in_data, NTAG215File& out_data) { 236void Cipher(const DerivedKeys& keys, const NTAG215File& in_data, NTAG215File& out_data) {
247 mbedtls_aes_context aes; 237 mbedtls_aes_context aes;
248 std::size_t nc_off = 0; 238 std::size_t nc_off = 0;
249 std::array<u8, 0x10> nonce_counter{}; 239 std::array<u8, sizeof(keys.aes_iv)> nonce_counter{};
250 std::array<u8, 0x10> stream_block{}; 240 std::array<u8, sizeof(keys.aes_iv)> stream_block{};
251 241
252 mbedtls_aes_setkey_enc(&aes, keys.aes_key.data(), 128); 242 const auto aes_key_size = static_cast<u32>(keys.aes_key.size() * 8);
253 memcpy(nonce_counter.data(), keys.aes_iv.data(), sizeof(nonce_counter)); 243 mbedtls_aes_setkey_enc(&aes, keys.aes_key.data(), aes_key_size);
254 244 memcpy(nonce_counter.data(), keys.aes_iv.data(), sizeof(keys.aes_iv));
255 std::array<u8, sizeof(NTAG215File)> in_data_byes{}; 245
256 std::array<u8, sizeof(NTAG215File)> out_data_bytes{}; 246 constexpr std::size_t encrypted_data_size = HMAC_TAG_START - SETTINGS_START;
257 memcpy(in_data_byes.data(), &in_data, sizeof(NTAG215File)); 247 mbedtls_aes_crypt_ctr(&aes, encrypted_data_size, &nc_off, nonce_counter.data(),
258 memcpy(out_data_bytes.data(), &out_data, sizeof(NTAG215File)); 248 stream_block.data(),
259 249 reinterpret_cast<const unsigned char*>(&in_data.settings),
260 mbedtls_aes_crypt_ctr(&aes, 0x188, &nc_off, nonce_counter.data(), stream_block.data(), 250 reinterpret_cast<unsigned char*>(&out_data.settings));
261 in_data_byes.data() + 0x2c, out_data_bytes.data() + 0x2c); 251
262 252 // Copy the rest of the data directly
263 memcpy(out_data_bytes.data(), in_data_byes.data(), 0x008); 253 out_data.uuid2 = in_data.uuid2;
264 // Data signature NOT copied 254 out_data.static_lock = in_data.static_lock;
265 memcpy(out_data_bytes.data() + 0x028, in_data_byes.data() + 0x028, 0x004); 255 out_data.compability_container = in_data.compability_container;
266 // Tag signature NOT copied 256
267 memcpy(out_data_bytes.data() + 0x1D4, in_data_byes.data() + 0x1D4, 0x048); 257 out_data.constant_value = in_data.constant_value;
268 258 out_data.write_counter = in_data.write_counter;
269 memcpy(&out_data, out_data_bytes.data(), sizeof(NTAG215File)); 259
260 out_data.uuid = in_data.uuid;
261 out_data.model_info = in_data.model_info;
262 out_data.keygen_salt = in_data.keygen_salt;
263 out_data.dynamic_lock = in_data.dynamic_lock;
264 out_data.CFG0 = in_data.CFG0;
265 out_data.CFG1 = in_data.CFG1;
266 out_data.password = in_data.password;
270} 267}
271 268
272bool LoadKeys(InternalKey& locked_secret, InternalKey& unfixed_info) { 269bool LoadKeys(InternalKey& locked_secret, InternalKey& unfixed_info) {
@@ -309,26 +306,26 @@ bool DecodeAmiibo(const EncryptedNTAG215File& encrypted_tag_data, NTAG215File& t
309 // Decrypt 306 // Decrypt
310 Cipher(data_keys, encoded_data, tag_data); 307 Cipher(data_keys, encoded_data, tag_data);
311 308
312 std::array<u8, sizeof(NTAG215File)> out{};
313 memcpy(out.data(), &tag_data, sizeof(NTAG215File));
314
315 // Regenerate tag HMAC. Note: order matters, data HMAC depends on tag HMAC! 309 // Regenerate tag HMAC. Note: order matters, data HMAC depends on tag HMAC!
310 constexpr std::size_t input_length = DYNAMIC_LOCK_START - UUID_START;
316 mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), tag_keys.hmac_key.data(), 311 mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), tag_keys.hmac_key.data(),
317 sizeof(HmacKey), out.data() + 0x1D4, 0x34, out.data() + HMAC_POS_TAG); 312 sizeof(HmacKey), reinterpret_cast<const unsigned char*>(&tag_data.uuid),
313 input_length, reinterpret_cast<unsigned char*>(&tag_data.hmac_tag));
318 314
319 // Regenerate data HMAC 315 // Regenerate data HMAC
316 constexpr std::size_t input_length2 = DYNAMIC_LOCK_START - WRITE_COUNTER_START;
320 mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), data_keys.hmac_key.data(), 317 mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), data_keys.hmac_key.data(),
321 sizeof(HmacKey), out.data() + 0x29, 0x1DF, out.data() + HMAC_POS_DATA); 318 sizeof(HmacKey),
322 319 reinterpret_cast<const unsigned char*>(&tag_data.write_counter), input_length2,
323 memcpy(&tag_data, out.data(), sizeof(NTAG215File)); 320 reinterpret_cast<unsigned char*>(&tag_data.hmac_data));
324 321
325 if (memcmp(tag_data.unfixed_hash.data(), encrypted_tag_data.user_memory.unfixed_hash.data(), 322 if (tag_data.hmac_data != encrypted_tag_data.user_memory.hmac_data) {
326 32) != 0) { 323 LOG_ERROR(Service_NFP, "hmac_data doesn't match");
327 return false; 324 return false;
328 } 325 }
329 326
330 if (memcmp(tag_data.locked_hash.data(), encrypted_tag_data.user_memory.locked_hash.data(), 327 if (tag_data.hmac_tag != encrypted_tag_data.user_memory.hmac_tag) {
331 32) != 0) { 328 LOG_ERROR(Service_NFP, "hmac_tag doesn't match");
332 return false; 329 return false;
333 } 330 }
334 331
@@ -347,13 +344,14 @@ bool EncodeAmiibo(const NTAG215File& tag_data, EncryptedNTAG215File& encrypted_t
347 const auto data_keys = GenerateKey(unfixed_info, tag_data); 344 const auto data_keys = GenerateKey(unfixed_info, tag_data);
348 const auto tag_keys = GenerateKey(locked_secret, tag_data); 345 const auto tag_keys = GenerateKey(locked_secret, tag_data);
349 346
350 std::array<u8, sizeof(NTAG215File)> plain{}; 347 NTAG215File encoded_tag_data{};
351 std::array<u8, sizeof(NTAG215File)> cipher{};
352 memcpy(plain.data(), &tag_data, sizeof(NTAG215File));
353 348
354 // Generate tag HMAC 349 // Generate tag HMAC
350 constexpr std::size_t input_length = DYNAMIC_LOCK_START - UUID_START;
351 constexpr std::size_t input_length2 = HMAC_TAG_START - WRITE_COUNTER_START;
355 mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), tag_keys.hmac_key.data(), 352 mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), tag_keys.hmac_key.data(),
356 sizeof(HmacKey), plain.data() + 0x1D4, 0x34, cipher.data() + HMAC_POS_TAG); 353 sizeof(HmacKey), reinterpret_cast<const unsigned char*>(&tag_data.uuid),
354 input_length, reinterpret_cast<unsigned char*>(&encoded_tag_data.hmac_tag));
357 355
358 // Init mbedtls HMAC context 356 // Init mbedtls HMAC context
359 mbedtls_md_context_t ctx; 357 mbedtls_md_context_t ctx;
@@ -362,17 +360,18 @@ bool EncodeAmiibo(const NTAG215File& tag_data, EncryptedNTAG215File& encrypted_t
362 360
363 // Generate data HMAC 361 // Generate data HMAC
364 mbedtls_md_hmac_starts(&ctx, data_keys.hmac_key.data(), sizeof(HmacKey)); 362 mbedtls_md_hmac_starts(&ctx, data_keys.hmac_key.data(), sizeof(HmacKey));
365 mbedtls_md_hmac_update(&ctx, plain.data() + 0x029, 0x18B); // Data 363 mbedtls_md_hmac_update(&ctx, reinterpret_cast<const unsigned char*>(&tag_data.write_counter),
366 mbedtls_md_hmac_update(&ctx, cipher.data() + HMAC_POS_TAG, 0x20); // Tag HMAC 364 input_length2); // Data
367 mbedtls_md_hmac_update(&ctx, plain.data() + 0x1D4, 0x34); 365 mbedtls_md_hmac_update(&ctx, reinterpret_cast<unsigned char*>(&encoded_tag_data.hmac_tag),
368 mbedtls_md_hmac_finish(&ctx, cipher.data() + HMAC_POS_DATA); 366 sizeof(HashData)); // Tag HMAC
367 mbedtls_md_hmac_update(&ctx, reinterpret_cast<const unsigned char*>(&tag_data.uuid),
368 input_length);
369 mbedtls_md_hmac_finish(&ctx, reinterpret_cast<unsigned char*>(&encoded_tag_data.hmac_data));
369 370
370 // HMAC cleanup 371 // HMAC cleanup
371 mbedtls_md_free(&ctx); 372 mbedtls_md_free(&ctx);
372 373
373 // Encrypt 374 // Encrypt
374 NTAG215File encoded_tag_data{};
375 memcpy(&encoded_tag_data, cipher.data(), sizeof(NTAG215File));
376 Cipher(data_keys, tag_data, encoded_tag_data); 375 Cipher(data_keys, tag_data, encoded_tag_data);
377 376
378 // Convert back to hardware 377 // Convert back to hardware
diff --git a/src/core/hle/service/nfp/amiibo_crypto.h b/src/core/hle/service/nfp/amiibo_crypto.h
index 9b021a5eb..af7335912 100644
--- a/src/core/hle/service/nfp/amiibo_crypto.h
+++ b/src/core/hle/service/nfp/amiibo_crypto.h
@@ -10,23 +10,23 @@
10struct mbedtls_md_context_t; 10struct mbedtls_md_context_t;
11 11
12namespace Service::NFP::AmiiboCrypto { 12namespace Service::NFP::AmiiboCrypto {
13constexpr std::size_t HMAC_POS_DATA = 0x8; 13// Byte locations in Service::NFP::NTAG215File
14constexpr std::size_t HMAC_POS_TAG = 0x1B4; 14constexpr std::size_t HMAC_DATA_START = 0x8;
15constexpr std::size_t SETTINGS_START = 0x2c;
16constexpr std::size_t WRITE_COUNTER_START = 0x29;
17constexpr std::size_t HMAC_TAG_START = 0x1B4;
18constexpr std::size_t UUID_START = 0x1D4;
19constexpr std::size_t DYNAMIC_LOCK_START = 0x208;
15 20
16using HmacKey = std::array<u8, 0x10>; 21using HmacKey = std::array<u8, 0x10>;
17using DrgbOutput = std::array<u8, 0x20>; 22using DrgbOutput = std::array<u8, 0x20>;
18 23
19struct HashSeed { 24struct HashSeed {
20 union { 25 u16 magic;
21 std::array<u8, 0x40> raw; 26 std::array<u8, 0xE> padding;
22 struct { 27 std::array<u8, 0x8> uuid1;
23 u16 magic; 28 std::array<u8, 0x8> uuid2;
24 std::array<u8, 0xE> padding; 29 std::array<u8, 0x20> keygen_salt;
25 std::array<u8, 0x8> uuid1;
26 std::array<u8, 0x8> uuid2;
27 std::array<u8, 0x20> keygen_salt;
28 } data;
29 };
30}; 30};
31static_assert(sizeof(HashSeed) == 0x40, "HashSeed is an invalid size"); 31static_assert(sizeof(HashSeed) == 0x40, "HashSeed is an invalid size");
32 32
@@ -71,12 +71,11 @@ u32 GetTagPassword(const TagUuid& uuid);
71HashSeed GetSeed(const NTAG215File& data); 71HashSeed GetSeed(const NTAG215File& data);
72 72
73// Middle step on the generation of derived keys 73// Middle step on the generation of derived keys
74void PreGenerateKey(const InternalKey& key, const HashSeed& seed, u8* output, 74std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed);
75 std::size_t& outputLen);
76 75
77// Initializes mbedtls context 76// Initializes mbedtls context
78void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key, 77void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key,
79 const u8* seed, std::size_t seed_size); 78 const std::vector<u8>& seed);
80 79
81// Feeds data to mbedtls context to generate the derived key 80// Feeds data to mbedtls context to generate the derived key
82void CryptoStep(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, DrgbOutput& output); 81void CryptoStep(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, DrgbOutput& output);
diff --git a/src/core/hle/service/nfp/amiibo_types.h b/src/core/hle/service/nfp/amiibo_types.h
index c9c0932d0..bf2de811a 100644
--- a/src/core/hle/service/nfp/amiibo_types.h
+++ b/src/core/hle/service/nfp/amiibo_types.h
@@ -137,10 +137,10 @@ struct EncryptedAmiiboFile {
137 u16 write_counter; // Number of times the amiibo has been written? 137 u16 write_counter; // Number of times the amiibo has been written?
138 INSERT_PADDING_BYTES(0x1); // Unknown 1 138 INSERT_PADDING_BYTES(0x1); // Unknown 1
139 AmiiboSettings settings; // Encrypted amiibo settings 139 AmiiboSettings settings; // Encrypted amiibo settings
140 HashData locked_hash; // Hash 140 HashData hmac_tag; // Hash
141 AmiiboModelInfo model_info; // Encrypted amiibo model info 141 AmiiboModelInfo model_info; // Encrypted amiibo model info
142 HashData keygen_salt; // Salt 142 HashData keygen_salt; // Salt
143 HashData unfixed_hash; // Hash 143 HashData hmac_data; // Hash
144 Service::Mii::Ver3StoreData owner_mii; // Encrypted Mii data 144 Service::Mii::Ver3StoreData owner_mii; // Encrypted Mii data
145 u64_be title_id; // Encrypted Game id 145 u64_be title_id; // Encrypted Game id
146 u16_be applicaton_write_counter; // Encrypted Counter 146 u16_be applicaton_write_counter; // Encrypted Counter
@@ -155,7 +155,7 @@ struct NTAG215File {
155 std::array<u8, 0x2> uuid2; 155 std::array<u8, 0x2> uuid2;
156 u16 static_lock; // Set defined pages as read only 156 u16 static_lock; // Set defined pages as read only
157 u32 compability_container; // Defines available memory 157 u32 compability_container; // Defines available memory
158 HashData unfixed_hash; // Hash 158 HashData hmac_data; // Hash
159 u8 constant_value; // Must be A5 159 u8 constant_value; // Must be A5
160 u16 write_counter; // Number of times the amiibo has been written? 160 u16 write_counter; // Number of times the amiibo has been written?
161 INSERT_PADDING_BYTES(0x1); // Unknown 1 161 INSERT_PADDING_BYTES(0x1); // Unknown 1
@@ -167,7 +167,7 @@ struct NTAG215File {
167 std::array<u8, 0x2> unknown; 167 std::array<u8, 0x2> unknown;
168 HashData hash; // Probably a SHA256-HMAC hash? 168 HashData hash; // Probably a SHA256-HMAC hash?
169 ApplicationArea application_area; // Encrypted Game data 169 ApplicationArea application_area; // Encrypted Game data
170 HashData locked_hash; // Hash 170 HashData hmac_tag; // Hash
171 std::array<u8, 0x8> uuid; 171 std::array<u8, 0x8> uuid;
172 AmiiboModelInfo model_info; 172 AmiiboModelInfo model_info;
173 HashData keygen_salt; // Salt 173 HashData keygen_salt; // Salt