1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010, Flavio D. Garcia, Peter van Rossum, Roel Verdult
3 // and Ronny Wichers Schreur. Radboud University Nijmegen
4 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // See LICENSE.txt for the text of the license.
17 //-----------------------------------------------------------------------------
18 // SecureMemory, CryptoMemory and CryptoRF library
19 //-----------------------------------------------------------------------------
21 #include "cryptolib.h"
34 static uint8_t nibbles_to_byte(nibble b0
, nibble b1
) {
35 // Combine both nibbles
36 return ((b0
<< 4) | b1
);
39 static uint8_t funny_mod(uint8_t a
, uint8_t m
) {
40 // Just return the input when this is less or equal than the modular value
43 // Compute the modular value
46 // Return the funny value, when the output was now zero, return the modular value
47 return (a
== 0) ? m
: a
;
50 static uint8_t bit_rotate_left(uint8_t a
, uint8_t n_bits
) {
51 // Rotate value a with the length of n_bits only 1 time
52 uint8_t mask
= (1 << n_bits
) - 1;
53 return ((a
<< 1) | (a
>> (n_bits
- 1))) & mask
;
57 static void reconstruct_nibbles(crypto_state s)
59 uint8_t b1, b5, b8, b15, b18;
60 uint8_t b0, b4, b7, b14, b17;
62 // Extract the bytes that generated the "previous" nibble
63 b1 = (uint8_t)((s->l >> 25) & 0x1f);
64 b5 = (uint8_t)((s->l >> 5) & 0x1f);
65 b8 = (uint8_t)((s->m >> 35) & 0x1f);
66 b15 = (uint8_t)((s->r >> 15) & 0x1f);
67 b18 = (uint8_t)(s->r & 0x1f);
69 // Reconstruct the b0 nibble
70 s->b0 = ((b1 ^ b5) & 0x0f) & ~(b8);
71 s->b0 |= ((b15 ^ b18) & 0x0f) & b8;
73 // Extract the bytes for the current nibble
74 b0 = (uint8_t)((s->l >> 30) & 0x1f);
75 b4 = (uint8_t)((s->l >> 10) & 0x1f);
76 b7 = (uint8_t)((s->m >> 42) & 0x1f);
77 b14 = (uint8_t)((s->r >> 20) & 0x1f);
78 b17 = (uint8_t)((s->r >> 5) & 0x1f);
80 // Construct the values for b1 generation
81 s->b1l = ((b0 ^ b4) & 0x0f);
82 s->b1r = ((b14 ^ b17) & 0x0f);
85 // Reconstruct the b1 nibble
86 s->b1 = s->b1l & ~(s->b1s);
87 s->b1 |= s->b1r & s->b1s;
90 static void next_left(uint8_t in
, crypto_state s
) {
93 // Update the left cipher state with the input byte
94 s
->l
^= ((in
& 0x1f) << 20);
96 // Extract the two (5 bits) values used for modular addtion
97 b3
= (uint8_t)((s
->l
>> 15) & 0x1f);
98 b6
= (uint8_t)(s
->l
& 0x1f);
100 // Compute the modular addition
101 bx
= funny_mod(b3
+ bit_rotate_left(b6
, 5), 0x1f);
103 // Rotate the left cipher state 5 bits
104 s
->l
= ((s
->l
>> 5) | ((uint64_t)bx
<< 30));
106 // Save the 4 left output bits used for b1
107 s
->b1l
= ((bx
^ b3
) & 0x0f);
110 static void next_right(uint8_t in
, crypto_state s
) {
111 uint8_t b16
, b18
, bx
;
113 // Update the right cipher state with the input byte
114 s
->r
^= ((in
& 0xf8) << 12);
116 // Extract the two (5 bits) values used for modular addtion
117 b16
= (uint8_t)((s
->r
>> 10) & 0x1f);
118 b18
= (uint8_t)(s
->r
& 0x1f);
120 // Compute the modular addition
121 bx
= funny_mod(b18
+ b16
, 0x1f);
123 // Rotate the right cipher state 5 bits
124 s
->r
= ((s
->r
>> 5) | ((uint64_t)bx
<< 20));
126 // Save the 4 right output bits used for b1
127 s
->b1r
= ((bx
^ b16
) & 0x0f);
130 static void next_middle(uint8_t in
, crypto_state s
) {
131 uint8_t b12
, b13
, bx
;
133 // Update the middle cipher state with the input byte
134 s
->m
^= (((((uint64_t)in
<< 3) & 0x7f) | (in
>> 5)) << 14);
136 // Extract the two (7 bits) values used for modular addtion
137 b12
= (uint8_t)((s
->m
>> 7) & 0x7f);
138 b13
= (uint8_t)(s
->m
& 0x7f);
140 // Compute the modular addition
141 bx
= (funny_mod(b12
+ bit_rotate_left(b13
, 7), 0x7f));
143 // Rotate the middle cipher state 7 bits
144 s
->m
= ((s
->m
>> 7) | ((uint64_t)bx
<< 42));
146 // Save the 4 middle selector bits used for b1
150 static void next(const bool feedback
, uint8_t in
, crypto_state s
) {
151 // Initialize the (optional) input parameter
154 // Only Cryptomemory uses feedback
156 // Construct the cipher update 'a' from (input ^ feedback)
157 a
= in
^ nibbles_to_byte(s
->b0
, s
->b1
);
160 // Shift the cipher state
165 // For active states we can use the available (previous) 'b1' nibble,
166 // otherwise use reconstruct_nibbles() to generate them
167 // reconstruct_nibbles(s)
169 // The nible from b1 shifts to b0
172 // Construct the new value of nible b1
173 s
->b1
= s
->b1l
& ~(s
->b1s
);
174 s
->b1
|= s
->b1r
& s
->b1s
;
177 static void next_n(const bool feedback
, size_t n
, uint8_t in
, crypto_state s
) {
178 // While n-rounds left, shift the cipher
179 while (n
--) next(feedback
, in
, s
);
182 static void initialize(const bool feedback
, const uint8_t *Gc
, const uint8_t *Ci
, const uint8_t *Q
, const size_t n
, crypto_state s
) {
185 // Reset the cipher state
186 memset(s
, 0x00, sizeof(crypto_state_t
));
188 // Load in the ci (tag-nonce), together with the first half of Q (reader-nonce)
189 for (pos
= 0; pos
< 4; pos
++) {
190 next_n(feedback
, n
, Ci
[2 * pos
], s
);
191 next_n(feedback
, n
, Ci
[2 * pos
+ 1], s
);
192 next(feedback
, Q
[pos
], s
);
195 // Load in the diversified key (Gc), together with the second half of Q (reader-nonce)
196 for (pos
= 0; pos
< 4; pos
++) {
197 next_n(feedback
, n
, Gc
[2 * pos
], s
);
198 next_n(feedback
, n
, Gc
[2 * pos
+ 1], s
);
199 next(feedback
, Q
[pos
+ 4], s
);
203 static uint8_t cm_byte(crypto_state s
) {
204 // Construct keystream byte by combining both nibbles
205 return nibbles_to_byte(s
->b0
, s
->b1
);
208 static uint8_t sm_byte(crypto_state s
) {
211 // Construct keystream byte by combining 2 parts from 4 nibbles
212 next_n(false, 2, 0, s
);
214 next_n(false, 2, 0, s
);
220 void print_crypto_state(const char *text
, crypto_state s
) {
224 for (pos
= 6; pos
>= 0; pos
--)
225 printf(" %02x", (uint8_t)(s
->l
>> (pos
* 5)) & 0x1f);
228 for (pos
= 6; pos
>= 0; pos
--)
229 printf(" %02x", (uint8_t)(s
->m
>> (pos
* 7)) & 0x7f);
232 for (pos
= 4; pos
>= 0; pos
--)
233 printf(" %02x", (uint8_t)(s
->r
>> (pos
* 5)) & 0x1f);
235 printf(" | %02x", cm_byte(s
));
239 void sm_auth(const uint8_t *Gc
, const uint8_t *Ci
, const uint8_t *Q
, uint8_t *Ch
, uint8_t *Ci_1
, crypto_state s
) {
242 initialize(false, Gc
, Ci
, Q
, 1, s
);
244 // Generate challenge answer for Tag and Reader
245 for (pos
= 0; pos
< 8; pos
++) {
246 Ci_1
[pos
] = sm_byte(s
);
247 Ch
[pos
] = sm_byte(s
);
251 void cm_auth(const uint8_t *Gc
, const uint8_t *Ci
, const uint8_t *Q
, uint8_t *Ch
, uint8_t *Ci_1
, uint8_t *Ci_2
, crypto_state s
) {
254 initialize(true, Gc
, Ci
, Q
, 3, s
);
256 // Construct the reader-answer (challenge)
257 next_n(true, 6, 0, s
);
259 for (pos
= 1; pos
< 8; pos
++) {
260 next_n(true, 7, 0, s
);
261 Ch
[pos
] = cm_byte(s
);
264 // Construct the tag-answer (Ci+1 = ff .. .. .. .. .. .. ..)
266 for (pos
= 1; pos
< 8; pos
++) {
267 next_n(true, 2, 0, s
);
268 Ci_1
[pos
] = cm_byte(s
);
271 // Construct the session key (Ci+2)
272 for (pos
= 0; pos
< 8; pos
++) {
273 next_n(true, 2, 0, s
);
274 Ci_2
[pos
] = cm_byte(s
);
277 // Prepare the cipher for encryption by shifting 3 more times
278 next_n(true, 3, 0, s
);
281 static void cm_crypt(const CryptoAction ca
, const uint8_t offset
, const uint8_t len
, const uint8_t *in
, uint8_t *out
, crypto_state s
) {
284 next_n(true, 5, 0, s
);
285 next(true, offset
, s
);
286 next_n(true, 5, 0, s
);
288 for (pos
= 0; pos
< len
; pos
++) {
289 // Perform the crypto operation
290 uint8_t bt
= in
[pos
] ^ cm_byte(s
);
293 if (out
) out
[pos
] = bt
;
295 // Detect where to find the plaintext for loading into cipher state
296 if (ca
== CA_DECRYPT
) {
299 next(true, in
[pos
], s
);
302 // Shift the cipher state 5 times
303 next_n(true, 5, 0, s
);
307 void cm_encrypt(const uint8_t offset
, const uint8_t len
, const uint8_t *pt
, uint8_t *ct
, crypto_state s
) {
308 next_n(true, 5, 0, s
);
310 cm_crypt(CA_ENCRYPT
, offset
, len
, pt
, ct
, s
);
313 void cm_decrypt(const uint8_t offset
, const uint8_t len
, const uint8_t *ct
, uint8_t *pt
, crypto_state s
) {
314 next_n(true, 5, 0, s
);
316 cm_crypt(CA_DECRYPT
, offset
, len
, ct
, pt
, s
);
319 void cm_grind_read_system_zone(const uint8_t offset
, const uint8_t len
, const uint8_t *pt
, crypto_state s
) {
320 cm_crypt(CA_ENCRYPT
, offset
, len
, pt
, NULL
, s
);
323 void cm_grind_set_user_zone(const uint8_t zone
, crypto_state s
) {
327 void cm_mac(uint8_t *mac
, crypto_state s
) {
328 next_n(true, 10, 0, s
);
332 next_n(true, 5, 0, s
);
337 void cm_password(const uint8_t *pt
, uint8_t *ct
, crypto_state s
) {
338 for (size_t pos
= 0; pos
< 3; pos
++) {
339 next_n(true, 5, pt
[pos
], s
);
340 ct
[pos
] = cm_byte(s
);