Update id48lib

* Add its own CMakeLists.txt
* Add id48 unit tests for its recovery API
* Add id48 unit tests for its generator API
* Add id48 espresso files, generator for those files, and validation test

* Proxmark3-specific:
  * update client/Makefile
  * update client/deps/id48lib.cmake
  *
This commit is contained in:
Henry Gabryjelski
2025-10-20 17:58:59 -07:00
parent c1441eb2ab
commit 563abf66ed
33 changed files with 2284 additions and 75 deletions
+4 -2
View File
@@ -45,13 +45,15 @@ Makefile.platform.*
# cmake
CMakeFiles/
deps/
client/CMakeFiles/
client/deps/
client/deps/**
!client/deps/id48/
!client/deps/id48/**
client/build/
client/android/build/
CMakeCache.txt
*.cmake
.cache
# Coverity
cov-int/
+1
View File
@@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Updated id48lib (adds unit tests, better build management)
- Added two trace files for Ultralight AES (@iceman1001)
- Added support for Ultralight AES secure messaing in `hf 14a raw` (@iceman1001)
- Added support for Ultralight AES secure messaging in `hf mfu info/rdbl/wrbl/dump/ndefread/wipe/setkey` (@iceman1001)
+3
View File
@@ -26,6 +26,9 @@ endif
ifeq ($(DEFSBEENHERE),)
-include ../../../Makefile.defs
endif
ifeq ($(DEFSBEENHERE),)
-include ../../../../Makefile.defs
endif
ifeq ($(DEFSBEENHERE),)
$(error Can't find Makefile.defs)
endif
+3 -2
View File
@@ -74,8 +74,9 @@ HARDNESTEDLIB = $(HARDNESTEDLIBPATH)/libhardnested.a
HARDNESTEDLIBLD =
## ID48
ID48LIBPATH = ./deps/id48
ID48LIBINC = -I$(ID48LIBPATH)
## must be manually kept in sync with updates to deps/id48/CMakeLists.txt
ID48LIBPATH = ./deps/id48/src
ID48LIBINC = -I$(ID48LIBPATH)/../public
ID48LIB = $(ID48LIBPATH)/libid48.a
ID48LIBLD =
+52
View File
@@ -0,0 +1,52 @@
# Now ignore any "build" directory anywhere under this directory
build/
**/build/
*.log
*.eml
*.html
*.o
*.a
*.d
*.elf
*.s19
*.map
*.bin
*.dll
*.moc.cpp
*.z
*.gz
*.Td
*.DS_Store
*.exe
*.dsym
*.json
*.old
*.swp
*.json.bak
*.pyc
*.bmp
# cmake
CMakeFiles/
client/CMakeFiles/
client/deps/**
!client/deps/id48/
!client/deps/id48/**
client/build/
client/android/build/
CMakeCache.txt
*.cmake
.cache
# Coverity
cov-int/
.coverity.conf
# .tmp files are created during compilation
*.tmp
# local codeql
_codeql*
/codeql
+13
View File
@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.21)
project(id48_project LANGUAGES C CXX ASM)
# Project-wide language standards (subdirectories inherit if not overridden)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(src)
add_subdirectory(tests)
+22
View File
@@ -48,3 +48,25 @@ provided the first half of the key, and at least one successful
authentication trio of nonce, challenge, and response, then
the library can recover all potentially valid values for the
second half of the key.
## Building
This project uses CMake, and thus should be easy to integrate
into any existing project using CMake.
The following commands can be run from the root of this depot,
and places all build artifacts into `./build`:
```bash
# Configure cmake for the current environment
# -S: explicitly specify the source directory
# -B: explicitly specify the directory for build artifacts
cmake -S . -B build
# Optionally (recommended) do a clean build each time
cmake --build ./build --parallel --target clean
# build everything
cmake --build ./build --parallel --target all
```
+58 -58
View File
@@ -160,63 +160,63 @@ of the key influences a given output bit.
Start state + key bit --> output
| Start state | Key bit | Output |
|-------|-------|----------------|
| `s₀₀` | `K₃₉` | << hidden >> |
| `s₀₁` | `K₃₈` | << hidden >> |
| `s₀₂` | `K₃₇` | << hidden >> |
| `s₀₃` | `K₃₆` | << hidden >> |
| `s₀₄` | `K₃₅` | << hidden >> |
| `s₀₅` | `K₃₄` | << hidden >> |
| `s₀₆` | `K₃₃` | << hidden >> |
| `s₀₇` | `K₃₂` | `O₀₀ == frn₀₀` |
| `s₀₈` | `K₃₁` | `O₀₁ == frn₀₁` |
| `s₀₉` | `K₃₀` | `O₀₂ == frn₀₂` |
| `s₁₀` | `K₂₉` | `O₀₃ == frn₀₃` |
| `s₁₁` | `K₂₈` | `O₀₄ == frn₀₄` |
| `s₁₂` | `K₂₇` | `O₀₅ == frn₀₅` |
| `s₁₃` | `K₂₆` | `O₀₆ == frn₀₆` |
| `s₁₄` | `K₂₅` | `O₀₇ == frn₀₇` |
| `s₁₅` | `K₂₄` | `O₀₈ == frn₀₈` |
| `s₁₆` | `K₂₃` | `O₀₉ == frn₀₉` |
| `s₁₇` | `K₂₂` | `O₁₀ == frn₁₀` |
| `s₁₈` | `K₂₁` | `O₁₁ == frn₁₁` |
| `s₁₉` | `K₂₀` | `O₁₂ == frn₁₂` |
| `s₂₀` | `K₁₉` | `O₁₃ == frn₁₃` |
| `s₂₁` | `K₁₈` | `O₁₄ == frn₁₄` |
| `s₂₂` | `K₁₇` | `O₁₅ == frn₁₅` |
| `s₂₃` | `K₁₆` | `O₁₆ == frn₁₆` |
| `s₂₄` | `K₁₅` | `O₁₇ == frn₁₇` |
| `s₂₅` | `K₁₄` | `O₁₈ == frn₁₈` |
| `s₂₆` | `K₁₃` | `O₁₉ == frn₁₉` |
| `s₂₇` | `K₁₂` | `O₂₀ == frn₂₀` |
| `s₂₈` | `K₁₁` | `O₂₁ == frn₂₁` |
| `s₂₉` | `K₁₀` | `O₂₂ == frn₂₂` |
| `s₃₀` | `K₀₉` | `O₂₃ == frn₂₃` |
| `s₃₁` | `K₀₈` | `O₂₄ == frn₂₄` |
| `s₃₂` | `K₀₇` | `O₂₅ == frn₂₅` |
| `s₃₃` | `K₀₆` | `O₂₆ == frn₂₆` |
| `s₃₄` | `K₀₅` | `O₂₇ == frn₂₇` |
| `s₃₅` | `K₀₄` | `O₂₈ == grn₀₀` |
| `s₃₆` | `K₀₃` | `O₂₉ == grn₀₁` |
| `s₃₇` | `K₀₂` | `O₃₀ == grn₀₂` |
| `s₃₈` | `K₀₁` | `O₃₁ == grn₀₃` |
| `s₃₉` | `K₀₀` | `O₃₂ == grn₀₄` |
| `s₄₀` | `0₁₄` | `O₃₃ == grn₀₅` |
| `s₄₁` | `0₁₃` | `O₃₄ == grn₀₆` |
| `s₄₂` | `0₁₂` | `O₃₅ == grn₀₇` |
| `s₄₃` | `0₁₁` | `O₃₆ == grn₀₈` |
| `s₄₄` | `0₁₀` | `O₃₇ == grn₀₉` |
| `s₄₅` | `0₀₉` | `O₃₈ == grn₁₀` |
| `s₄₆` | `0₀₈` | `O₃₉ == grn₁₁` |
| `s₄₇` | `0₀₇` | `O₄₀ == grn₁₂` |
| `s₄₈` | `0₀₆` | `O₄₁ == grn₁₃` |
| `s₄₉` | `0₀₅` | `O₄₂ == grn₁₄` |
| `s₅₀` | `0₀₄` | `O₄₃ == grn₁₅` |
| `s₅₁` | `0₀₃` | `O₄₄ == grn₁₆` |
| `s₅₂` | `0₀₂` | `O₄₅ == grn₁₇` |
| `s₅₃` | `0₀₁` | `O₄₆ == grn₁₈` |
| `s₅₄` | `0₀₀` | `O₄₇ == grn₁₉` |
| Start state | Key bit | Output | Notes |
|-------|-------|----------------|-------|
| `s₀₀` | `K₃₉` | << hidden >> | Seven ... |
| `s₀₁` | `K₃₈` | << hidden >> | .. iterations ... |
| `s₀₂` | `K₃₇` | << hidden >> | .. before ... |
| `s₀₃` | `K₃₆` | << hidden >> | .. any ... |
| `s₀₄` | `K₃₅` | << hidden >> | .. output ... |
| `s₀₅` | `K₃₄` | << hidden >> | .. bits ... |
| `s₀₆` | `K₃₃` | << hidden >> | .. seen. |
| `s₀₇` | `K₃₂` | `O₀₀ == frn₀₀` | |
| `s₀₈` | `K₃₁` | `O₀₁ == frn₀₁` | |
| `s₀₉` | `K₃₀` | `O₀₂ == frn₀₂` | |
| `s₁₀` | `K₂₉` | `O₀₃ == frn₀₃` | |
| `s₁₁` | `K₂₈` | `O₀₄ == frn₀₄` | |
| `s₁₂` | `K₂₇` | `O₀₅ == frn₀₅` | |
| `s₁₃` | `K₂₆` | `O₀₆ == frn₀₆` | |
| `s₁₄` | `K₂₅` | `O₀₇ == frn₀₇` | |
| `s₁₅` | `K₂₄` | `O₀₈ == frn₀₈` | |
| `s₁₆` | `K₂₃` | `O₀₉ == frn₀₉` | |
| `s₁₇` | `K₂₂` | `O₁₀ == frn₁₀` | |
| `s₁₈` | `K₂₁` | `O₁₁ == frn₁₁` | |
| `s₁₉` | `K₂₀` | `O₁₂ == frn₁₂` | |
| `s₂₀` | `K₁₉` | `O₁₃ == frn₁₃` | |
| `s₂₁` | `K₁₈` | `O₁₄ == frn₁₄` | |
| `s₂₂` | `K₁₇` | `O₁₅ == frn₁₅` | |
| `s₂₃` | `K₁₆` | `O₁₆ == frn₁₆` | |
| `s₂₄` | `K₁₅` | `O₁₇ == frn₁₇` | |
| `s₂₅` | `K₁₄` | `O₁₈ == frn₁₈` | |
| `s₂₆` | `K₁₃` | `O₁₉ == frn₁₉` | |
| `s₂₇` | `K₁₂` | `O₂₀ == frn₂₀` | |
| `s₂₈` | `K₁₁` | `O₂₁ == frn₂₁` | |
| `s₂₉` | `K₁₀` | `O₂₂ == frn₂₂` | |
| `s₃₀` | `K₀₉` | `O₂₃ == frn₂₃` | |
| `s₃₁` | `K₀₈` | `O₂₄ == frn₂₄` | |
| `s₃₂` | `K₀₇` | `O₂₅ == frn₂₅` | |
| `s₃₃` | `K₀₆` | `O₂₆ == frn₂₆` | |
| `s₃₄` | `K₀₅` | `O₂₇ == frn₂₇` | Last key bit that affects `frn` |
| `s₃₅` | `K₀₄` | `O₂₈ == grn₀₀` | Five bits of key affect `grn` |
| `s₃₆` | `K₀₃` | `O₂₉ == grn₀₁` | |
| `s₃₇` | `K₀₂` | `O₃₀ == grn₀₂` | |
| `s₃₈` | `K₀₁` | `O₃₁ == grn₀₃` | |
| `s₃₉` | `K₀₀` | `O₃₂ == grn₀₄` | |
| `s₄₀` | `0₁₄` | `O₃₃ == grn₀₅` | Zero-fill start |
| `s₄₁` | `0₁₃` | `O₃₄ == grn₀₆` | |
| `s₄₂` | `0₁₂` | `O₃₅ == grn₀₇` | |
| `s₄₃` | `0₁₁` | `O₃₆ == grn₀₈` | |
| `s₄₄` | `0₁₀` | `O₃₇ == grn₀₉` | |
| `s₄₅` | `0₀₉` | `O₃₈ == grn₁₀` | |
| `s₄₆` | `0₀₈` | `O₃₉ == grn₁₁` | |
| `s₄₇` | `0₀₇` | `O₄₀ == grn₁₂` | |
| `s₄₈` | `0₀₆` | `O₄₁ == grn₁₃` | |
| `s₄₉` | `0₀₅` | `O₄₂ == grn₁₄` | |
| `s₅₀` | `0₀₄` | `O₄₃ == grn₁₅` | |
| `s₅₁` | `0₀₃` | `O₄₄ == grn₁₆` | |
| `s₅₂` | `0₀₂` | `O₄₅ == grn₁₇` | |
| `s₅₃` | `0₀₁` | `O₄₆ == grn₁₈` | |
| `s₅₄` | `0₀₀` | `O₄₇ == grn₁₉` | |
@@ -525,7 +525,7 @@ FPGA logic if desired.
There are sixteen (`16x`) blocks of memory, each storing a 16-bit value.
Blocks may be protected (`P` column) as read-only (`RO`) or write-only (`WO`).
`Lock₀` === Disable writingPermanent write-prevention when set to 1.
`Lock₀` === Disable writing ... (?) write-prevention when set to 1.
`Lock₁` === Pin-code lock
| `Block` | `P` | `Purpose` | Bits (LSB first) | Bits (MSB first) |
+46
View File
@@ -0,0 +1,46 @@
# ###################
# Generating .PLA
# ###################
.i 5
.o 1
.ilb a l2 l3 l0 l6
.ob g1
00000 1
00001 1
00010 1
00011 1
00100 0
00101 0
00110 1
00111 0
01000 0
01001 1
01010 0
01011 0
01100 1
01101 0
01110 0
01111 1
10000 1
10001 0
10010 0
10011 0
10100 0
10101 1
10110 0
10111 1
11000 0
11001 0
11010 1
11011 1
11100 1
11101 1
11110 1
11111 0
.e
# ###################
# END OF .PLA
# ###################
+46
View File
@@ -0,0 +1,46 @@
# ###################
# Generating .PLA
# ###################
.i 5
.o 1
.ilb l5 b m0 l4 m1
.ob g2
00000 1
00001 1
00010 1
00011 1
00100 0
00101 0
00110 0
00111 1
01000 0
01001 1
01010 0
01011 0
01100 1
01101 0
01110 1
01111 0
10000 1
10001 0
10010 0
10011 0
10100 0
10101 1
10110 1
10111 0
11000 0
11001 0
11010 1
11011 1
11100 1
11101 1
11110 0
11111 1
.e
# ###################
# END OF .PLA
# ###################
+46
View File
@@ -0,0 +1,46 @@
# ###################
# Generating .PLA
# ###################
.i 5
.o 1
.ilb m5 c r1 m3 r3
.ob g3
00000 1
00001 1
00010 1
00011 1
00100 0
00101 0
00110 0
00111 1
01000 0
01001 0
01010 1
01011 0
01100 1
01101 1
01110 0
01111 0
10000 1
10001 0
10010 0
10011 0
10100 0
10101 1
10110 1
10111 0
11000 0
11001 1
11010 0
11011 1
11100 1
11101 0
11110 1
11111 1
.e
# ###################
# END OF .PLA
# ###################
+46
View File
@@ -0,0 +1,46 @@
# ###################
# Generating .PLA
# ###################
.i 5
.o 1
.ilb r2 r4 r6 r0 r5
.ob g4
00000 1
00001 1
00010 1
00011 1
00100 0
00101 0
00110 0
00111 1
01000 0
01001 0
01010 1
01011 0
01100 1
01101 1
01110 0
01111 0
10000 0
10001 1
10010 0
10011 0
10100 1
10101 0
10110 1
10111 0
11000 1
11001 0
11010 0
11011 1
11100 0
11101 1
11110 1
11111 1
.e
# ###################
# END OF .PLA
# ###################
+270
View File
@@ -0,0 +1,270 @@
# ###################
# Generating .PLA
# ###################
.i 8
.o 1
.ilb l0 l4 l6 m1 m3 r0 r3 r5
.ob XX
00000000 0
00000001 0
00000010 1
00000011 0
00000100 0
00000101 0
00000110 1
00000111 0
00001000 1
00001001 1
00001010 1
00001011 1
00001100 1
00001101 1
00001110 1
00001111 1
00010000 1
00010001 1
00010010 1
00010011 1
00010100 0
00010101 0
00010110 1
00010111 0
00011000 1
00011001 1
00011010 1
00011011 1
00011100 0
00011101 0
00011110 1
00011111 0
00100000 1
00100001 0
00100010 1
00100011 0
00100100 1
00100101 0
00100110 1
00100111 0
00101000 1
00101001 1
00101010 1
00101011 1
00101100 1
00101101 1
00101110 1
00101111 1
00110000 1
00110001 0
00110010 1
00110011 0
00110100 1
00110101 0
00110110 1
00110111 0
00111000 1
00111001 0
00111010 1
00111011 0
00111100 1
00111101 0
00111110 1
00111111 0
01000000 0
01000001 0
01000010 1
01000011 1
01000100 0
01000101 0
01000110 1
01000111 1
01001000 1
01001001 1
01001010 1
01001011 1
01001100 1
01001101 1
01001110 1
01001111 1
01010000 1
01010001 1
01010010 1
01010011 1
01010100 0
01010101 0
01010110 1
01010111 1
01011000 1
01011001 1
01011010 1
01011011 1
01011100 0
01011101 0
01011110 1
01011111 0
01100000 0
01100001 0
01100010 1
01100011 1
01100100 0
01100101 0
01100110 1
01100111 1
01101000 1
01101001 1
01101010 1
01101011 1
01101100 1
01101101 1
01101110 1
01101111 1
01110000 0
01110001 0
01110010 1
01110011 1
01110100 0
01110101 0
01110110 1
01110111 1
01111000 0
01111001 0
01111010 1
01111011 0
01111100 0
01111101 0
01111110 1
01111111 0
10000000 0
10000001 0
10000010 0
10000011 0
10000100 0
10000101 0
10000110 0
10000111 0
10001000 0
10001001 0
10001010 0
10001011 0
10001100 0
10001101 0
10001110 0
10001111 0
10010000 1
10010001 1
10010010 1
10010011 1
10010100 0
10010101 0
10010110 0
10010111 0
10011000 1
10011001 1
10011010 1
10011011 1
10011100 0
10011101 0
10011110 0
10011111 0
10100000 1
10100001 0
10100010 1
10100011 0
10100100 1
10100101 0
10100110 1
10100111 0
10101000 1
10101001 0
10101010 1
10101011 0
10101100 1
10101101 0
10101110 1
10101111 0
10110000 1
10110001 0
10110010 1
10110011 0
10110100 1
10110101 0
10110110 1
10110111 0
10111000 1
10111001 0
10111010 1
10111011 0
10111100 1
10111101 0
10111110 1
10111111 0
11000000 0
11000001 0
11000010 1
11000011 1
11000100 0
11000101 0
11000110 1
11000111 1
11001000 0
11001001 0
11001010 0
11001011 0
11001100 0
11001101 0
11001110 0
11001111 0
11010000 1
11010001 1
11010010 1
11010011 1
11010100 0
11010101 0
11010110 1
11010111 1
11011000 1
11011001 1
11011010 1
11011011 1
11011100 0
11011101 0
11011110 0
11011111 0
11100000 0
11100001 0
11100010 1
11100011 1
11100100 0
11100101 0
11100110 1
11100111 1
11101000 0
11101001 0
11101010 0
11101011 0
11101100 0
11101101 0
11101110 0
11101111 0
11110000 0
11110001 0
11110010 1
11110011 1
11110100 0
11110101 0
11110110 1
11110111 1
11111000 0
11111001 0
11111010 0
11111011 0
11111100 0
11111101 0
11111110 0
11111111 0
.e
# ###################
# END OF .PLA
# ###################
@@ -31,13 +31,13 @@
#include <string.h>
#include <stdbool.h>
#if defined(NDEBUG)
#define ASSERT(x) ((void)0)
#define ASSERT(x) ((void)0)
#elif defined(ID48_NO_STDIO)
#define ASSERT(x) ((void)0)
#define ASSERT(x) ((void)0)
#else // neither NDEBUG nor ID48_NO_STDIO defined
#include <stdio.h>
#include <assert.h>
#define ASSERT(x) assert((x))
#include <stdio.h>
#include <assert.h>
#define ASSERT(x) assert((x))
#endif
+25
View File
@@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.21)
project(id48lib LANGUAGES C CXX ASM)
add_library(id48lib STATIC
id48_data.c
id48_generator.c
id48_recover.c
)
# Compile options/warnings for C sources only (use generator expression)
target_compile_options(id48lib PRIVATE
$<$<COMPILE_LANGUAGE:C>:-Wpedantic -Wall -Werror -O3 -Wno-unknown-pragmas -Wno-inline -Wno-unused-function>
)
# Prefer compile_definitions over embedding -D in compile options
target_compile_definitions(id48lib PRIVATE ID48_NO_STDIO)
# Private include dirs for internal headers, PUBLIC for the library API
target_include_directories(id48lib
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/id48
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../public
)
set_property(TARGET id48lib PROPERTY POSITION_INDEPENDENT_CODE ON)
@@ -1,6 +1,6 @@
# Makefile for ID48LIB library
# Proxmark3-specific Makefile for ID48LIB library
MYSRCPATHS =
MYINCLUDES = -I.
MYINCLUDES = -I../public
MYCFLAGS = -Wpedantic -Wall -Werror -O3 -Wno-unknown-pragmas -Wno-inline -Wno-unused-function
MYDEFS = -DID48_NO_STDIO
MYSRCS = \
@@ -10,4 +10,4 @@ MYSRCS = \
LIB_A = libid48.a
include ../../../Makefile.host
include ../../../../Makefile.host

Some files were not shown because too many files have changed in this diff Show More