First attempt disambiguous nonce implementation

This commit is contained in:
noproto
2024-08-14 02:25:57 -04:00
parent 6332ec7478
commit 01b19483c5
5 changed files with 108 additions and 117 deletions

View File

@@ -206,8 +206,7 @@ uint32_t lfsr_rollback_word(Crypto1* crypto1, uint32_t in, int fb) {
return ret;
}
// Return true if the nonce is invalid else return false
bool valid_nonce(uint32_t nt, uint32_t ks, uint8_t nt_par_enc) {
bool nonce_matches_encrypted_parity_bits(uint32_t nt, uint32_t ks, uint8_t nt_par_enc) {
return (nfc_util_even_parity8((nt >> 24) & 0xFF) ==
(((nt_par_enc >> 3) & 1) ^ FURI_BIT(ks, 16))) &&
(nfc_util_even_parity8((nt >> 16) & 0xFF) ==
@@ -215,3 +214,23 @@ bool valid_nonce(uint32_t nt, uint32_t ks, uint8_t nt_par_enc) {
(nfc_util_even_parity8((nt >> 8) & 0xFF) ==
(((nt_par_enc >> 1) & 1) ^ FURI_BIT(ks, 0)));
}
bool is_weak_prng_nonce(uint32_t nonce) {
if(nonce == 0) return false;
uint16_t x = nonce >> 16;
x = (x & 0xff) << 8 | x >> 8;
for(uint8_t i = 0; i < 16; i++) {
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
}
x = (x & 0xff) << 8 | x >> 8;
return x == (nonce & 0xFFFF);
}
uint32_t decrypt_nt_enc(uint32_t cuid, uint32_t nt_enc, MfClassicKey known_key) {
uint64_t known_key_int = bit_lib_bytes_to_num_be(known_key.data, 6);
Crypto1 crypto_temp;
crypto1_init(&crypto_temp, known_key_int);
crypto1_word(&crypto_temp, nt_enc ^ cuid, 1);
uint32_t decrypted_nt_enc = (nt_enc ^ lfsr_rollback_word(&crypto_temp, nt_enc ^ cuid, 1));
return decrypted_nt_enc;
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include "protocols/mf_classic/mf_classic.h"
#include <toolbox/bit_buffer.h>
#ifdef __cplusplus
@@ -40,7 +41,11 @@ void crypto1_encrypt_reader_nonce(
uint32_t lfsr_rollback_word(Crypto1* crypto1, uint32_t in, int fb);
bool valid_nonce(uint32_t nt, uint32_t ks, uint8_t nt_par_enc);
bool nonce_matches_encrypted_parity_bits(uint32_t nt, uint32_t ks, uint8_t nt_par_enc);
bool is_weak_prng_nonce(uint32_t nonce);
uint32_t decrypt_nt_enc(uint32_t cuid, uint32_t nt_enc, MfClassicKey known_key);
uint32_t prng_successor(uint32_t x, uint32_t n);