|
| Error | ParseCommand (const std::uint8_t *capdu, std::size_t len, CommandFields *f) noexcept |
| | Split a serialized C-APDU into data and Le (ISO/IEC 7816-4 section 5.1, cases 1, 2S/E, 3S/E, 4S/E).
|
| |
| Error | WrapCommand (ChannelState &st, const std::uint8_t *capdu, std::size_t capdu_len, std::uint8_t *out, std::size_t out_cap, std::size_t *out_len) noexcept |
| | C-MAC + C-ENC wrap of a C-APDU in any ISO/IEC 7816-4 case, short or extended.
|
| |
| void | WipeChannel (ChannelState &st) noexcept |
| | End a session: wipe the session keys, MAC chaining value and counter, mark it closed.
|
| |
| Error | UnwrapResponse (ChannelState &st, const std::uint8_t *rapdu, std::size_t rapdu_len, std::uint8_t *out, std::size_t out_cap, std::size_t *out_len) noexcept |
| | R-MAC check and R-ENC decryption of one response. Increments the counter on success.
|
| |
| bool | FillPutKeyBlock (std::uint8_t *block, const std::uint8_t current_dek[crypto::kAes128KeyLen], const std::uint8_t plain[crypto::kAes128KeyLen], std::uint8_t kcv3[kPutKeyKcvLen]) noexcept |
| | One AES key field inside GP PUT KEY (encrypted with the current DEK).
|
| |
| Error | BuildPutKey (std::uint8_t key_version, const std::uint8_t current_dek[crypto::kAes128KeyLen], const std::uint8_t new_enc[crypto::kAes128KeyLen], const std::uint8_t new_mac[crypto::kAes128KeyLen], const std::uint8_t new_dek[crypto::kAes128KeyLen], std::uint8_t *capdu, std::size_t capdu_cap, std::size_t *capdu_len, std::uint8_t *expect_rsp, std::size_t expect_cap, std::size_t *expect_len) noexcept |
| | Build GP PUT KEY (CLA 0x80, INS 0xD8, P1 = key version, P2 0x81).
|
| |
| Error se050::scp03::BuildPutKey |
( |
std::uint8_t |
key_version, |
|
|
const std::uint8_t |
current_dek[crypto::kAes128KeyLen], |
|
|
const std::uint8_t |
new_enc[crypto::kAes128KeyLen], |
|
|
const std::uint8_t |
new_mac[crypto::kAes128KeyLen], |
|
|
const std::uint8_t |
new_dek[crypto::kAes128KeyLen], |
|
|
std::uint8_t * |
capdu, |
|
|
std::size_t |
capdu_cap, |
|
|
std::size_t * |
capdu_len, |
|
|
std::uint8_t * |
expect_rsp, |
|
|
std::size_t |
expect_cap, |
|
|
std::size_t * |
expect_len |
|
) |
| |
|
inlinenoexcept |
Build GP PUT KEY (CLA 0x80, INS 0xD8, P1 = key version, P2 0x81).
Replaces ISD key set key_version (product: 0x0B) with new_enc, new_mac, new_dek. The current DEK encrypts the new key values. Caller must have an open SCP03 session with the current set. Never embeds NXP default key bytes.
- Parameters
-
| expect_rsp | Version byte + three 3-byte KCVs the card must echo. |
| Error se050::scp03::UnwrapResponse |
( |
ChannelState & |
st, |
|
|
const std::uint8_t * |
rapdu, |
|
|
std::size_t |
rapdu_len, |
|
|
std::uint8_t * |
out, |
|
|
std::size_t |
out_cap, |
|
|
std::size_t * |
out_len |
|
) |
| |
|
inlinenoexcept |
R-MAC check and R-ENC decryption of one response. Increments the counter on success.
GPC Amendment D 6.2.5 / 6.2.7 (security level 0x33): every response in the session carries an R-MAC over the MAC chaining value, the encrypted data and SW1 SW2. A response that is shorter than R-MAC + SW (for example a bare 90 00 an attacker injects on the bus), whose R-MAC does not match, or whose padding is invalid returns Error::Authentication, and the channel is closed with its keys wiped. Nothing from such a response is written to out. The MAC is compared in constant time and checked before anything is decrypted.
| Error se050::scp03::WrapCommand |
( |
ChannelState & |
st, |
|
|
const std::uint8_t * |
capdu, |
|
|
std::size_t |
capdu_len, |
|
|
std::uint8_t * |
out, |
|
|
std::size_t |
out_cap, |
|
|
std::size_t * |
out_len |
|
) |
| |
|
inlinenoexcept |
C-MAC + C-ENC wrap of a C-APDU in any ISO/IEC 7816-4 case, short or extended.
GPC Amendment D 6.2.4 / 6.2.6: the command data is padded (80 00..) and encrypted with the command ICV, then the MAC is computed over the MAC chaining value, the header (CLA with the secure-messaging bit) and the new Lc and data. The wrapped command uses extended length when the input did or when the new Lc exceeds 255. When the input had an Le, the wrapped command keeps one, set to the maximum (00, or 00 00 extended): the protected answer is longer than the plain one by its padding and R-MAC, so the plain Ne cannot be reused. Le is not covered by the C-MAC. A command without data still gets one encrypted padding block (SE050 erratum JOS.2, see the comment in the body). Caller owns out (CM4: D2 .se_apdu_scratch); kWrapScratchBytes covers short commands, kWrapScratchBytesExtended any command. Updates the MCV. The command counter moves on in UnwrapResponse once the card has answered.