-
-
Notifications
You must be signed in to change notification settings - Fork 393
Description
Issue Description
When trying to scan a Mii QR code generated from the 3DS it gives "mac check in CCM failed"
Soru thinks this is likely because the 3DS does not implement aes-ccm correctly in hardware, as for the mac calculation it assumes that the buffer is a multiple of 0x10 bytes large. This is not the case for miis, as there the buffer is 0x68 bytes large (0x08 bytes of the 0x70 byte buffer are used for the nonce, instead of the ciphertext). Sadly soru can't seem to find the documentation for that in the 3dbrew wiki for that currently.
So, as a TL;DR: AES-CCM needs nopadding for the ciphertext but it needs padding for the verification of the mac.
When looking into tagmo's source code, it is implemented here:
TagMo/app/src/main/java/com/hiddenramblings/tagmo/qrcode/QRCodeScanner.kt
Lines 183 to 195 in 8f2a1ff
| private fun decryptMii(qrData: ByteArray?) { | |
| if (null == qrData) return | |
| val nonce = qrData.copyOfRange(0, 8) | |
| val ivSpec = nonce.plus(byteArrayOf(0, 0, 0, 0)) | |
| val cipher = Cipher.getInstance("AES/CCM/NoPadding") | |
| cipher.init( | |
| Cipher.DECRYPT_MODE, keySpec, | |
| GCMParameterSpec(ivSpec.size * Byte.SIZE_BITS, ivSpec) | |
| ) | |
| val content = cipher.doFinal(qrData, 0, 0x58) | |
| txtMiiValue.text = content.copyOfRange(0, 12).plus(nonce) | |
| .plus(content.copyOfRange(12, content.size)).toHex() | |
| } |
In sorus implementation of encrypting / decrypting miis, she decrypts without verifying the mac, then encrypts again, with padded 0x8 0-bytes, and then verifies the re-encrypted mac. You can find this here, if you need to: https://gitlab.com/3ds-netpass/netpass-server/-/blob/main/src/types/mii.rs?ref_type=heads#L307
Logcat Output
No usb cable for phone atm, can fill in if neededUsage Requirements
- I have read and understood the usage requirements for TagMo