From 9ade745f07a8ae90a4a6b700fbb7666e2ef0a39a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 19 Aug 2020 21:38:21 +0200 Subject: [PATCH] rework cryptorf --- Makefile.defs | 1 + Makefile.host | 22 ++- common/cryptorf/cryptolib.c | 367 +++++++++++++++++++++++++++++++++++ common/cryptorf/cryptolib.h | 60 ++++++ tools/cryptorf/Makefile | 46 ++--- tools/cryptorf/cm.c | 45 +++-- tools/cryptorf/crf.c | 294 ---------------------------- tools/cryptorf/cryptolib.c | 359 ---------------------------------- tools/cryptorf/cryptolib.h | 56 ------ tools/cryptorf/defines.h | 36 ---- tools/cryptorf/laundry.sh | 2 - tools/cryptorf/sm.c | 32 +-- tools/cryptorf/sma.cpp | 147 +++++++------- tools/cryptorf/sma_multi.cpp | 174 +++++++++-------- tools/cryptorf/util.c | 18 +- tools/cryptorf/util.h | 19 +- 16 files changed, 693 insertions(+), 985 deletions(-) create mode 100644 common/cryptorf/cryptolib.c create mode 100644 common/cryptorf/cryptolib.h delete mode 100644 tools/cryptorf/crf.c delete mode 100644 tools/cryptorf/cryptolib.c delete mode 100644 tools/cryptorf/cryptolib.h delete mode 100644 tools/cryptorf/defines.h delete mode 100755 tools/cryptorf/laundry.sh diff --git a/Makefile.defs b/Makefile.defs index fb8a7a45b..1c702930a 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -48,6 +48,7 @@ else RANLIB= ranlib endif +DEFCXXFLAGS = -Wall -Werror -O3 -pipe DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe # Some more warnings we want as errors: DEFCFLAGS += -Wbad-function-cast -Wredundant-decls -Wmissing-prototypes -Wchar-subscripts -Wshadow -Wundef -Wwrite-strings -Wunused -Wuninitialized -Wpointer-arith -Winline -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wmissing-declarations -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits -Wold-style-definition diff --git a/Makefile.host b/Makefile.host index 07b8c2199..e374a9294 100644 --- a/Makefile.host +++ b/Makefile.host @@ -17,6 +17,8 @@ endif CFLAGS ?= $(DEFCFLAGS) CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES) +CXXFLAGS ?= $(DEFCXXFLAGS) +CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES) LDFLAGS += $(MYLDFLAGS) LDLIBS += $(MYLDLIBS) @@ -31,6 +33,7 @@ BINDIR := . OBJDIR := obj MYOBJS ?= $(MYSRCS:%.c=$(OBJDIR)/%.o) +MYCXXOBJS ?= $(MYCXXSRCS:%.cpp=$(OBJDIR)/%.o) CLEAN = $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin)) all: $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin)) @@ -61,24 +64,31 @@ endif .PHONY: all clean install uninstall -$(BINDIR)/$(LIB_A): $(MYOBJS) +$(BINDIR)/$(LIB_A): $(MYOBJS) $(MYCXXOBJS) $(info [=] AR $(notdir $@)) - $(Q)$(AR) $@ $(MYOBJS) + $(Q)$(AR) $@ $(MYOBJS) $(MYCXXOBJS) $(Q)$(RANLIB) $@ -$(BINDIR)/% : $(OBJDIR)/%.o $(MYOBJS) $(MYLIBS) +$(BINDIR)/% : $(OBJDIR)/%.o $(MYOBJS) $(MYCXXOBJS) $(MYLIBS) $(info [=] LD $(notdir $@)) - $(Q)$(LD) $(LDFLAGS) $(MYOBJS) $< -o $@ $(MYLIBS) $(MYLDLIBS) + $(Q)$(LD) $(LDFLAGS) $(MYOBJS) $(MYCXXOBJS) $< -o $@ $(MYLIBS) $(MYLDLIBS) -$(OBJDIR)/%.o : %.c | $(OBJDIR) +%.o: %.c +$(OBJDIR)/%.o : %.c $(OBJDIR)/%.d | $(OBJDIR) $(info [-] CC $<) $(Q)$(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $< $(Q)$(POSTCOMPILE) +%.o: %.cpp +$(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d | $(OBJDIR) + $(info [-] CXX $<) + $(Q)$(CXX) $(DEPFLAGS) $(CXXFLAGS) -c -o $@ $< + $(Q)$(POSTCOMPILE) + $(OBJDIR): $(Q)$(MKDIR) $(OBJDIR) -DEPENDENCY_FILES = $(MYOBJS:%.o=%.d) $(BINS:%=$(OBJDIR)/%.d) +DEPENDENCY_FILES = $(MYOBJS:%.o=%.d) $(MYCXXOBJS:%.o=%.d) $(BINS:%=$(OBJDIR)/%.d) $(DEPENDENCY_FILES): ; .PRECIOUS: $(DEPENDENCY_FILES) diff --git a/common/cryptorf/cryptolib.c b/common/cryptorf/cryptolib.c new file mode 100644 index 000000000..26b07f824 --- /dev/null +++ b/common/cryptorf/cryptolib.c @@ -0,0 +1,367 @@ +/* + * + * SecureMemory, CryptoMemory and CryptoRF library + * + * Copyright (C) 2010, Flavio D. Garcia, Peter van Rossum, Roel Verdult + * and Ronny Wichers Schreur. Radboud University Nijmegen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "cryptolib.h" +#include +#include +#include +#include + +typedef enum { + CA_ENCRYPT = 0x01, + CA_DECRYPT = 0x02 +} CryptoAction; + +int counter = 0; + +static uint8_t nibbles_to_byte(nibble b0, nibble b1) +{ + // Combine both nibbles + return ((b0 << 4) | b1); +} + +static uint8_t funny_mod(uint8_t a, uint8_t m) +{ + // Just return the input when this is less or equal than the modular value + if (a < m) return a; + + // Compute the modular value + a %= m; + + // Return the funny value, when the output was now zero, return the modular value + return (a == 0) ? m : a; +} + +static uint8_t bit_rotate_left(uint8_t a, uint8_t n_bits) +{ + // Rotate value a with the length of n_bits only 1 time + uint8_t mask = (1 << n_bits) - 1; + return ((a << 1) | (a >> (n_bits - 1))) & mask; +} + +/* +static void reconstruct_nibbles(crypto_state s) +{ + uint8_t b1, b5, b8, b15, b18; + uint8_t b0, b4, b7, b14, b17; + + // Extract the bytes that generated the "previous" nibble + b1 = (uint8_t)((s->l >> 25) & 0x1f); + b5 = (uint8_t)((s->l >> 5) & 0x1f); + b8 = (uint8_t)((s->m >> 35) & 0x1f); + b15 = (uint8_t)((s->r >> 15) & 0x1f); + b18 = (uint8_t)(s->r & 0x1f); + + // Reconstruct the b0 nibble + s->b0 = ((b1 ^ b5) & 0x0f) & ~(b8); + s->b0 |= ((b15 ^ b18) & 0x0f) & b8; + + // Extract the bytes for the current nibble + b0 = (uint8_t)((s->l >> 30) & 0x1f); + b4 = (uint8_t)((s->l >> 10) & 0x1f); + b7 = (uint8_t)((s->m >> 42) & 0x1f); + b14 = (uint8_t)((s->r >> 20) & 0x1f); + b17 = (uint8_t)((s->r >> 5) & 0x1f); + + // Construct the values for b1 generation + s->b1l = ((b0 ^ b4) & 0x0f); + s->b1r = ((b14 ^ b17) & 0x0f); + s->b1s = b7; + + // Reconstruct the b1 nibble + s->b1 = s->b1l & ~(s->b1s); + s->b1 |= s->b1r & s->b1s; +} +*/ +static void next_left(uint8_t in, crypto_state s) +{ + uint8_t b3, b6, bx; + + // Update the left cipher state with the input byte + s->l ^= ((in & 0x1f) << 20); + + // Extract the two (5 bits) values used for modular addtion + b3 = (uint8_t)((s->l >> 15) & 0x1f); + b6 = (uint8_t)(s->l & 0x1f); + + // Compute the modular addition + bx = funny_mod(b3 + bit_rotate_left(b6, 5), 0x1f); + + // Rotate the left cipher state 5 bits + s->l = ((s->l >> 5) | ((uint64_t)bx << 30)); + + // Save the 4 left output bits used for b1 + s->b1l = ((bx ^ b3) & 0x0f); +} + +static void next_right(uint8_t in, crypto_state s) +{ + uint8_t b16, b18, bx; + + // Update the right cipher state with the input byte + s->r ^= ((in & 0xf8) << 12); + + // Extract the two (5 bits) values used for modular addtion + b16 = (uint8_t)((s->r >> 10) & 0x1f); + b18 = (uint8_t)(s->r & 0x1f); + + // Compute the modular addition + bx = funny_mod(b18 + b16, 0x1f); + + // Rotate the right cipher state 5 bits + s->r = ((s->r >> 5) | ((uint64_t)bx << 20)); + + // Save the 4 right output bits used for b1 + s->b1r = ((bx ^ b16) & 0x0f); +} + +static void next_middle(uint8_t in, crypto_state s) +{ + uint8_t b12, b13, bx; + + // Update the middle cipher state with the input byte + s->m ^= (((((uint64_t)in << 3) & 0x7f) | (in >> 5)) << 14); + + // Extract the two (7 bits) values used for modular addtion + b12 = (uint8_t)((s->m >> 7) & 0x7f); + b13 = (uint8_t)(s->m & 0x7f); + + // Compute the modular addition + bx = (funny_mod(b12 + bit_rotate_left(b13, 7), 0x7f)); + + // Rotate the middle cipher state 7 bits + s->m = ((s->m >> 7) | ((uint64_t)bx << 42)); + + // Save the 4 middle selector bits used for b1 + s->b1s = bx & 0x0f; +} + +static void next(const bool feedback, uint8_t in, crypto_state s) +{ + // Initialize the (optional) input parameter + uint8_t a = in; + + // Only Cryptomemory uses feedback + if (feedback) { + // Construct the cipher update 'a' from (input ^ feedback) + a = in ^ nibbles_to_byte(s->b0, s->b1); + } + + // Shift the cipher state + next_left(a, s); + next_middle(a, s); + next_right(a, s); + + // For active states we can use the available (previous) 'b1' nibble, + // otherwise use reconstruct_nibbles() to generate them + // reconstruct_nibbles(s) + + // The nible from b1 shifts to b0 + s->b0 = s->b1; + + // Construct the new value of nible b1 + s->b1 = s->b1l & ~(s->b1s); + s->b1 |= s->b1r & s->b1s; +} + +static void next_n(const bool feedback, size_t n, uint8_t in, crypto_state s) +{ + // While n-rounds left, shift the cipher + while (n--) next(feedback, in, s); +} + +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) +{ + size_t pos; + + // Reset the cipher state + memset(s, 0x00, sizeof(crypto_state_t)); + + // Load in the ci (tag-nonce), together with the first half of Q (reader-nonce) + for (pos = 0; pos < 4; pos++) { + next_n(feedback, n, Ci[2 * pos ], s); + next_n(feedback, n, Ci[2 * pos + 1], s); + next(feedback, Q[pos], s); + } + + // Load in the diversified key (Gc), together with the second half of Q (reader-nonce) + for (pos = 0; pos < 4; pos++) { + next_n(feedback, n, Gc[2 * pos ], s); + next_n(feedback, n, Gc[2 * pos + 1], s); + next(feedback, Q[pos + 4], s); + } +} + +static uint8_t cm_byte(crypto_state s) +{ + // Construct keystream byte by combining both nibbles + return nibbles_to_byte(s->b0, s->b1); +} + +static uint8_t sm_byte(crypto_state s) +{ + uint8_t ks; + + // Construct keystream byte by combining 2 parts from 4 nibbles + next_n(false, 2, 0, s); + ks = s->b1 << 4; + next_n(false, 2, 0, s); + ks |= s->b1; + + return ks; +} + +void print_crypto_state(const char *text, crypto_state s) +{ + int pos; + + printf("%s", text); + for (pos = 6; pos >= 0; pos--) + printf(" %02x", (uint8_t)(s->l >> (pos * 5)) & 0x1f); + + printf(" |"); + for (pos = 6; pos >= 0; pos--) + printf(" %02x", (uint8_t)(s->m >> (pos * 7)) & 0x7f); + + printf(" |"); + for (pos = 4; pos >= 0; pos--) + printf(" %02x", (uint8_t)(s->r >> (pos * 5)) & 0x1f); + + printf(" | %02x", cm_byte(s)); + printf("\n"); +} + +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) +{ + size_t pos; + + initialize(false, Gc, Ci, Q, 1, s); + + // Generate challange answer for Tag and Reader + for (pos = 0; pos < 8; pos++) { + Ci_1[pos] = sm_byte(s); + Ch[pos] = sm_byte(s); + } +} + +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) +{ + size_t pos; + + initialize(true, Gc, Ci, Q, 3, s); + + // Construct the reader-answer (challange) + next_n(true, 6, 0, s); + Ch[0] = cm_byte(s); + for (pos = 1; pos < 8; pos++) { + next_n(true, 7, 0, s); + Ch [pos] = cm_byte(s); + } + + // Construct the tag-answer (Ci+1 = ff .. .. .. .. .. .. ..) + Ci_1[0] = 0xff; + for (pos = 1; pos < 8; pos++) { + next_n(true, 2, 0, s); + Ci_1[pos] = cm_byte(s); + } + + // Construct the session key (Ci+2) + for (pos = 0; pos < 8; pos++) { + next_n(true, 2, 0, s); + Ci_2[pos] = cm_byte(s); + } + + // Prepare the cipher for encryption by shifting 3 more times + next_n(true, 3, 0, s); +} + +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) +{ + size_t pos; + uint8_t bt; + + next_n(true, 5, 0, s); + next(true, offset, s); + next_n(true, 5, 0, s); + next(true, len, s); + for (pos = 0; pos < len; pos++) { + // Perform the crypto operation + bt = in[pos] ^ cm_byte(s); + + // Generate output + if (out) out[pos] = bt; + + // Detect where to find the plaintext for loading into cipher state + if (ca == CA_DECRYPT) { + next(true, bt, s); + } else { + next(true, in[pos], s); + } + + // Shift the cipher state 5 times + next_n(true, 5, 0, s); + } +} + +void cm_encrypt(const uint8_t offset, const uint8_t len, const uint8_t *ct, uint8_t *pt, crypto_state s) +{ + next_n(true, 5, 0, s); + next(true, 0, s); + cm_crypt(CA_ENCRYPT, offset, len, ct, pt, s); +} + +void cm_decrypt(const uint8_t offset, const uint8_t len, const uint8_t *ct, uint8_t *pt, crypto_state s) +{ + next_n(true, 5, 0, s); + next(true, 0, s); + cm_crypt(CA_DECRYPT, offset, len, ct, pt, s); +} + +void cm_grind_read_system_zone(const uint8_t offset, const uint8_t len, const uint8_t *pt, crypto_state s) +{ + cm_crypt(CA_ENCRYPT, offset, len, pt, NULL, s); +} + +void cm_grind_set_user_zone(const uint8_t zone, crypto_state s) +{ + next(true, zone, s); +} + +void cm_mac(uint8_t *mac, crypto_state s) +{ + next_n(true, 10, 0, s); + if (mac) + mac[0] = cm_byte(s); + + next_n(true, 5, 0, s); + if (mac) + mac[1] = cm_byte(s); +} + +void cm_password(const uint8_t *pt, uint8_t *ct, crypto_state s) +{ + for (size_t pos = 0; pos < 3; pos++) { + next_n(true, 5, pt[pos], s); + ct[pos] = cm_byte(s); + } +} + diff --git a/common/cryptorf/cryptolib.h b/common/cryptorf/cryptolib.h new file mode 100644 index 000000000..0f31d8870 --- /dev/null +++ b/common/cryptorf/cryptolib.h @@ -0,0 +1,60 @@ +/* + * + * SecureMemory, CryptoMemory and CryptoRF library + * + * Copyright (C) 2010, Flavio D. Garcia, Peter van Rossum, Roel Verdult + * and Ronny Wichers Schreur. Radboud University Nijmegen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef _CRYPTOLIB_H_ +#define _CRYPTOLIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +// A nibble is actually only 4 bits, but there is no such type ;) +typedef uint8_t nibble; + +typedef struct { + uint64_t l; + uint64_t m; + uint64_t r; + nibble b0; + nibble b1; + nibble b1l; + nibble b1r; + nibble b1s; +} crypto_state_t; +typedef crypto_state_t *crypto_state; + +void print_crypto_state(const char *text, crypto_state s); +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); +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); +void cm_encrypt(const uint8_t offset, const uint8_t len, const uint8_t *pt, uint8_t *ct, crypto_state s); +void cm_decrypt(const uint8_t offset, const uint8_t len, const uint8_t *ct, uint8_t *pt, crypto_state s); +void cm_grind_read_system_zone(const uint8_t offset, const uint8_t len, const uint8_t *pt, crypto_state s); +void cm_grind_set_user_zone(const uint8_t zone, crypto_state s); +void cm_mac(uint8_t *mac, crypto_state s); +void cm_password(const uint8_t *pt, uint8_t *ct, crypto_state s); + +#ifdef __cplusplus +} +#endif +#endif // _CRYPTOLIB_H_ diff --git a/tools/cryptorf/Makefile b/tools/cryptorf/Makefile index 55842bd32..5ff3250e6 100644 --- a/tools/cryptorf/Makefile +++ b/tools/cryptorf/Makefile @@ -1,31 +1,23 @@ -CC = gcc -CXX = g++ -LD = gcc -LXX = g++ -CFLAGS = -W -Wall -O4 -CXXFLAGS = -W -Wall -O4 -std=c++11 -LDFLAGS = -LXXFLAGS = -lpthread +MYSRCPATHS = ../../common ../../common/cryptorf +MYSRCS = cryptolib.c util.c +MYINCLUDES = -I../../common/cryptorf +MYCFLAGS = +MYDEFS = +MYLDLIBS = -lpthread -OBJS = cryptolib.o util.o -HEADERS = cryptolib.h util.h -SRC = cryptolib.c util.c -EXES = cm sm sma sma_multi -#EXES = cm sm sma sma_multi crf +BINS = cm sm sma sma_multi +INSTALLTOOLS = $(BINS) -all: $(OBJS) $(EXES) +include ../../Makefile.host -%.o : %.c - $(CC) $(CFLAGS) -c -o $@ $< +# checking platform can be done only after Makefile.host +ifneq (,$(findstring MINGW,$(platform))) + # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) + # and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1 + CFLAGS += -D_ISOC99_SOURCE +endif -% : %.c $(OBJS) - $(LD) $(CFLAGS) $(LDFLAGS) -o $@ $< $(OBJS) - -% : %.cpp $(SRC) - $(LXX) $(CXXFLAGS) -o $@ $< $(SRC) $(LXXFLAGS) - -crf: crf.c $(OBJS) - $(LD) $(CFLAGS) $(LDFLAGS) -o crf $< $(OBJS) -lnfc - -clean: - rm -f $(OBJS) $(EXES) crf +cm : $(OBJDIR)/cm.o $(MYOBJS) +sm : $(OBJDIR)/sm.o $(MYOBJS) +sma : $(OBJDIR)/sma.o $(MYOBJS) +sma_multi : $(OBJDIR)/sma_multi.o $(MYOBJS) diff --git a/tools/cryptorf/cm.c b/tools/cryptorf/cm.c index 14e32844a..87e577b36 100644 --- a/tools/cryptorf/cm.c +++ b/tools/cryptorf/cm.c @@ -20,9 +20,16 @@ * */ -#include "defines.h" +#include +#include +#include #include "cryptolib.h" #include "util.h" +#ifdef _MSC_VER + // avoid scanf warnings in Visual Studio + #define _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_DEPRECATE +#endif int main(int argc, const char* argv[]) { @@ -30,24 +37,24 @@ int main(int argc, const char* argv[]) crypto_state_t s; // Main authentication values - byte_t Q[8]; // Reader key-auth random - byte_t Gc[8]; // Secret seed - byte_t Ci[8]; // Card random (last state) - byte_t Ch[8]; // Reader answer (challenge) - byte_t Ci_1[8]; // Card answer - byte_t Ci_2[8]; // Session key + uint8_t Q[8]; // Reader key-auth random + uint8_t Gc[8]; // Secret seed + uint8_t Ci[8]; // Card random (last state) + uint8_t Ch[8]; // Reader answer (challenge) + uint8_t Ci_1[8]; // Card answer + uint8_t Ci_2[8]; // Session key // Session authentication values - byte_t Qs[8]; // Reader session-auth random - byte_t Chs[8]; // Reader session-answer (challenge) - byte_t Ci_1s[8]; // Card answer for session - byte_t Ci_2s[8]; // Is this used? + uint8_t Qs[8]; // Reader session-auth random + uint8_t Chs[8]; // Reader session-answer (challenge) + uint8_t Ci_1s[8]; // Card answer for session + uint8_t Ci_2s[8]; // Is this used? // Various argument options - ui64 nGc; // Card secret - ui64 nCi; // Card random - ui64 nQ; // Reader main-random - ui64 nQs; // Reader session-random + uint64_t nGc; // Card secret + uint64_t nCi; // Card random + uint64_t nQ; // Reader main-random + uint64_t nQs; // Reader session-random // Show header and help syntax printf("CryptoMemory simulator - (c) Radboud University Nijmegen\n"); @@ -58,10 +65,10 @@ int main(int argc, const char* argv[]) } // Parse arguments - sscanf(argv[1],"%016llx",&nGc); num_to_bytes(nGc,8,Gc); - sscanf(argv[2],"%016llx",&nCi); num_to_bytes(nCi,8,Ci); - sscanf(argv[3],"%016llx",&nQ); num_to_bytes(nQ,8,Q); - sscanf(argv[4],"%016llx",&nQs); num_to_bytes(nQs,8,Qs); + sscanf(argv[1],"%016" SCNx64,&nGc); num_to_bytes(nGc,8,Gc); + sscanf(argv[2],"%016" SCNx64,&nCi); num_to_bytes(nCi,8,Ci); + sscanf(argv[3],"%016" SCNx64,&nQ); num_to_bytes(nQ,8,Q); + sscanf(argv[4],"%016" SCNx64,&nQs); num_to_bytes(nQs,8,Qs); // Calculate authentication cm_auth(Gc,Ci,Q,Ch,Ci_1,Ci_2,&s); diff --git a/tools/cryptorf/crf.c b/tools/cryptorf/crf.c deleted file mode 100644 index 044acce05..000000000 --- a/tools/cryptorf/crf.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * - * CryptoRF simulation - * - * Copyright (C) 2010, Flavio D. Garcia, Peter van Rossum, Roel Verdult - * and Ronny Wichers Schreur. Radboud University Nijmegen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "defines.h" -#include -#include -#include -#include "cryptolib.h" -#include "util.h" - -// ~dirty globals for lazy use of libnfc -static dev_info* pdi; // NFC device info -static tag_info ti; // Tag info (card serial, etc.) -byte_t abtRx[MAX_FRAME_LEN]; // Communication buffer -size_t szRxLen; // Length of communication buffer - -void print_decryption(const byte_t* ct, const byte_t* pt, size_t len) { - size_t pos,count; - - for (count = 0; count < len; count += 8) { - printf(" "); - for (pos = 0; pos < 8; pos++){ - if ((count+pos) "); - for (pos = 0; pos < 8; pos++) { - if ((count + pos) < len) { - printf("%02x ", pt[count + pos]); - } else { - printf(" "); - } - } - printf("\n"); - } -} - -bool transmit_bytes(const byte_t* pbtTx, const size_t szTxLen) { - printf("R: "); - print_bytes(pbtTx, szTxLen); - - // Transmit the command bytes - if (!nfc_initiator_transceive_bytes(pdi, pbtTx, szTxLen, abtRx, (uint32_t*)&szRxLen)) { - printf("\nERROR: Communication failed\n\n"); - nfc_disconnect(pdi); - exit(1); - } - - printf("T: "); - print_bytes(abtRx, szRxLen); - - // Succesful transfer - return true; -} - - -#define PWD_NOT_USED (uint32_t)(~0) - -int main(int argc, char* argv[]) { - // Various parameters - crypto_state_t s; // Cryptomemory state - size_t pos; // Position counter - - // Main authentication values - byte_t Q[8]; // Reader key-auth random - byte_t Gc[8]; // Secret seed - byte_t Ci[8]; // Card random (last state) - byte_t Ch[8]; // Reader answer (challenge) - byte_t Ci_1[8]; // Card answer - byte_t Ci_2[8]; // Session key - - // Session authentication values - byte_t Qs[8]; // Reader session-auth random - byte_t Chs[8]; // Reader session-answer (challenge) - byte_t Ci_1s[8]; // Card answer for session - byte_t Ci_2s[8]; // Is this used? - - // Various argument options - ui64 Gc0; // First card secret - uint32_t zone; // Number of userzone - uint32_t offset; // Offset address - uint32_t len; // Length - uint32_t pwd; // Optional read password - - // Application buffers - byte_t pt[MAX_FRAME_LEN]; // Plaintext - byte_t ct[MAX_FRAME_LEN]; // Ciphertext - byte_t mac[2]; - - byte_t crf_read_ci[2 + 2] = { 0x16,0x00,0x50,0x07 }; // Read first card random Ci0 (offset 50, len 8) - byte_t crf_check_pwd[2 + 3] = { 0x1c,0x00 }; // Provide (optional) read password - byte_t crf_auth[2 + 16] = { 0x18,0x00 }; // Authenticate using card secret Gc0 and Ci - byte_t crf_verify[2 + 16] = { 0x18,0x10 }; // Authenticate with session key - byte_t crf_set_zone[1 + 1] = { 0x11 }; // Set the userzone to read from - byte_t crf_read_zone[2 + 2] = { 0x12,0x00 }; // Read n-bytes from offset - byte_t crf_read_mac[ 4] = { 0x16,0x02,0xff,0x01 }; // Read n-bytes from offset - - // Show header and help syntax - printf("CryptoRF example - (c) Radboud University Nijmegen\n\n"); - if (argc < 5) { - printf("syntax: crf [pwd]\n\n"); - return 1; - } - - // Parse command-line arguments - sscanf(argv[1],"%016llx", &Gc0); - sscanf(argv[2],"%02x", &zone); - sscanf(argv[3],"%02x", &offset); - sscanf(argv[4],"%02x", &len); - - // Construct CryptoRF frames - num_to_bytes(Gc0, 8, Gc); - crf_set_zone[1] = zone; - crf_read_zone[2] = offset; - crf_read_zone[3] = (len == 0) ? 0 : (len - 1); - - // Check if the optional password argument was used - if (argc == 6) { - sscanf(argv[5], "%06x", &pwd); - num_to_bytes(pwd, 3, crf_check_pwd + 2); - } else { - pwd = PWD_NOT_USED; - } - - // Initialize randoms - srand((uint32_t)time(0)); - - for (pos = 0; pos < 8; pos++) { - Q[pos] = rand(); - Qs[pos] = rand(); - } - - // Try to open the NFC device - pdi = nfc_connect(NULL); - if (pdi == INVALID_DEVICE_INFO) { - printf("ERROR: Unable to connect to NFC device.\n"); - return 1; - } - nfc_initiator_init(pdi); - - // Drop the field for a while - nfc_configure(pdi, DCO_ACTIVATE_FIELD, true); - - // Let the reader only try once to find a tag - nfc_configure(pdi, DCO_INFINITE_SELECT, false); - - // Configure the CRC and Parity settings - nfc_configure(pdi, DCO_HANDLE_CRC, true); - nfc_configure(pdi, DCO_HANDLE_PARITY, true); - - printf("Connected to NFC device: %s\n\n", pdi->acName); - - // Poll for a ISO14443-B cryptomemory tag - if (!nfc_initiator_select_tag(pdi, IM_ISO14443B_106, (byte_t*)"\x00", 1, &ti)) { - printf("ERROR: Can not find a Atmel CryptoRF card.\n\n"); - nfc_disconnect(pdi); - return 1; - } - - printf("The following (NFC) ISO14443-B tag was found:\n\n"); - printf(" ATQB: "); print_bytes(ti.tib.abtAtqb, 12); - printf(" ID: "); print_bytes(ti.tib.abtId, 4); - printf(" CID: %02x\n", ti.tib.btCid); - printf(" PARAMS: %02x %02x %02x %02x\n\n" - ,ti.tib.btParam1 - ,ti.tib.btParam2 - ,ti.tib.btParam3 - ,ti.tib.btParam4 - ); - - - printf("Changing active userzone\n"); - transmit_bytes(crf_set_zone, sizeof(crf_set_zone)); - printf("\n"); - - if (pwd != PWD_NOT_USED) { - printf("Suppling password for communication\n"); - transmit_bytes(crf_check_pwd, sizeof(crf_check_pwd)); - printf("\n"); - } - - printf("Reading first Ci(0) from the system zone (offset = 0x50)\n"); - transmit_bytes(crf_read_ci, sizeof(crf_read_ci)); - printf("\n"); - - // Save the retrieved value of Ci - memcpy(Ci, abtRx + 2, 8); - - // Calculate key-authentication - printf("* Computing authentication values with card secret\n\n"); - cm_auth(Gc, Ci, Q, Ch, Ci_1, Ci_2, &s); - memcpy(crf_auth + 2, Q, 8); - memcpy(crf_auth + 10, Ch, 8); - - printf("Authenticate using Gc, Ci and random Q\n"); - transmit_bytes(crf_auth, sizeof(crf_auth)); - printf("\n"); - - printf("Reading new Ci value from the system zone (tag-answer)\n"); - transmit_bytes(crf_read_ci, sizeof(crf_read_ci)); - printf("\n"); - - if (memcmp(Ci_1, abtRx + 2, 8) != 0) { - printf("ERROR: Authentication failed\n\n"); - nfc_disconnect(pdi); - return 1; - } - - // Calculate session-authentication - printf("* Computing authentication values with session key\n\n"); - cm_auth(Ci_2, Ci_1, Qs, Chs, Ci_1s, Ci_2s, &s); - memcpy(crf_verify + 2, Qs, 8); - memcpy(crf_verify + 10, Chs, 8); - - printf("VerifyCrypto using session key and initialize encryption\n"); - transmit_bytes(crf_verify, sizeof(crf_verify)); - printf("\n"); - - printf("Reading new Ci value from the system zone (tag-answer)\n"); - transmit_bytes(crf_read_ci, sizeof(crf_read_ci)); - printf("\n"); - - if (memcmp(Ci_1s, abtRx + 2, 8) != 0) { - printf("ERROR: Session authentication failed\n\n"); - nfc_disconnect(pdi); - return 1; - } - - printf("* Updating the cipher by grinding Ci (offset,len,data)\n\n"); - cm_grind_read_system_zone(0x50, 8, Ci_1s, &s); - - printf("Read the data from the offset using the encrypted channel\n"); - transmit_bytes(crf_read_zone, sizeof(crf_read_zone)); - printf("\n"); - - if (abtRx[1] != 0) { - printf("ERROR: Reading failed, maybe you need to supply a password\n\n"); - nfc_disconnect(pdi); - return 1; - } - memcpy(ct, abtRx + 2, len); - - printf("* Decrypting..."); - cm_decrypt(offset, len, ct, pt, &s); - printf("done\n\n"); - print_decryption(ct, pt, len); - printf("\n"); - - if (pwd != PWD_NOT_USED) { - num_to_bytes(pwd, 3, pt); - cm_password(pt, crf_check_pwd + 2, &s); - printf("Testing the feature to supply an encrypted password\n"); - transmit_bytes(crf_check_pwd, sizeof(crf_check_pwd)); - printf("\n"); - } - - // Calculate and check mac - cm_mac(mac, &s); - printf("Verify checksum for the transaction: %02x %02x\n", mac[0], mac[1]); - transmit_bytes(crf_read_mac, sizeof(crf_read_mac)); - if (memcmp(mac, abtRx + 2, 2) != 0) { - printf("ERROR: MAC checksum failed\n\n"); - nfc_disconnect(pdi); - return 1; - } - - printf("Communication succesful!\n\n"); - nfc_disconnect(pdi); - return 0; -} - diff --git a/tools/cryptorf/cryptolib.c b/tools/cryptorf/cryptolib.c deleted file mode 100644 index 7390f0438..000000000 --- a/tools/cryptorf/cryptolib.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * - * SecureMemory, CryptoMemory and CryptoRF library - * - * Copyright (C) 2010, Flavio D. Garcia, Peter van Rossum, Roel Verdult - * and Ronny Wichers Schreur. Radboud University Nijmegen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "cryptolib.h" - -typedef enum { - CA_ENCRYPT = 0x01, - CA_DECRYPT = 0x02 -} CryptoAction; - -int counter=0; - -byte_t nibbles_to_byte(nibble b0, nibble b1) -{ - // Combine both nibbles - return ((b0<<4)|b1); -} - -byte_t funny_mod(byte_t a, byte_t m) -{ - // Just return the input when this is less or equal than the modular value - if (a> (n_bits - 1))) & mask; -} - -void reconstruct_nibbles(crypto_state s) -{ - byte_t b1,b5,b8,b15,b18; - byte_t b0,b4,b7,b14,b17; - - // Extract the bytes that generated the "previous" nibble - b1 = (byte_t)((s->l >> 25) & 0x1f); - b5 = (byte_t)((s->l >> 5) & 0x1f); - b8 = (byte_t)((s->m >> 35) & 0x1f); - b15 = (byte_t)((s->r >> 15) & 0x1f); - b18 = (byte_t)(s->r & 0x1f); - - // Reconstruct the b0 nibble - s->b0 = ((b1 ^ b5) & 0x0f) & ~(b8); - s->b0 |= ((b15 ^ b18) & 0x0f) & b8; - - // Extract the bytes for the current nibble - b0 = (byte_t)((s->l >> 30) & 0x1f); - b4 = (byte_t)((s->l >> 10) & 0x1f); - b7 = (byte_t)((s->m >> 42) & 0x1f); - b14 = (byte_t)((s->r >> 20) & 0x1f); - b17 = (byte_t)((s->r >> 5) & 0x1f); - - // Construct the values for b1 generation - s->b1l = ((b0 ^ b4) & 0x0f); - s->b1r = ((b14 ^ b17) & 0x0f); - s->b1s = b7; - - // Reconstruct the b1 nibble - s->b1 = s->b1l & ~(s->b1s); - s->b1 |= s->b1r & s->b1s; -} - -void next_left(byte_t in, crypto_state s) -{ - byte_t b3, b6, bx; - - // Update the left cipher state with the input byte - s->l ^= ((in & 0x1f) << 20); - - // Extract the two (5 bits) values used for modular addtion - b3 = (byte_t)((s->l >> 15) & 0x1f); - b6 = (byte_t)(s->l & 0x1f); - - // Compute the modular addition - bx = funny_mod(b3 + bit_rotate_left(b6,5),0x1f); - - // Rotate the left cipher state 5 bits - s->l = ((s->l >> 5)| ((uint64_t)bx << 30)); - - // Save the 4 left output bits used for b1 - s->b1l = ((bx^b3) & 0x0f); -} - -void next_right(byte_t in, crypto_state s) -{ - byte_t b16, b18, bx; - - // Update the right cipher state with the input byte - s->r ^= ((in & 0xf8) << 12); - - // Extract the two (5 bits) values used for modular addtion - b16 = (byte_t)((s->r >> 10) & 0x1f); - b18 = (byte_t)(s->r & 0x1f); - - // Compute the modular addition - bx = funny_mod(b18 + b16,0x1f); - - // Rotate the right cipher state 5 bits - s->r = ((s->r >> 5) | ((uint64_t)bx << 20)); - - // Save the 4 right output bits used for b1 - s->b1r = ((bx^b16) & 0x0f); -} - -void next_middle(byte_t in, crypto_state s) -{ - byte_t b12, b13, bx; - - // Update the middle cipher state with the input byte - s->m ^= (((((uint64_t)in << 3) & 0x7f) | (in >> 5)) << 14); - - // Extract the two (7 bits) values used for modular addtion - b12 = (byte_t)((s->m >> 7) & 0x7f); - b13 = (byte_t)(s->m & 0x7f); - - // Compute the modular addition - bx = (funny_mod(b12 + bit_rotate_left(b13,7),0x7f)); - - // Rotate the middle cipher state 7 bits - s->m = ((s->m >> 7)| ((uint64_t)bx << 42)); - - // Save the 4 middle selector bits used for b1 - s->b1s = bx & 0x0f; -} - -void next(const bool feedback, byte_t in, crypto_state s) -{ - // Initialize the (optional) input parameter - byte_t a = in; - - // Only Cryptomemory uses feedback - if (feedback) - { - // Construct the cipher update 'a' from (input ^ feedback) - a = in ^ nibbles_to_byte(s->b0,s->b1); - } - - // Shift the cipher state - next_left(a,s); - next_middle(a,s); - next_right(a,s); - - // For active states we can use the available (previous) 'b1' nibble, - // otherwise use reconstruct_nibbles() to generate them - // reconstruct_nibbles(s) - - // The nible from b1 shifts to b0 - s->b0 = s->b1; - - // Construct the new value of nible b1 - s->b1 = s->b1l & ~(s->b1s); - s->b1 |= s->b1r & s->b1s; -} - -void next_n(const bool feedback, size_t n, byte_t in, crypto_state s) -{ - // While n-rounds left, shift the cipher - while (n--) next(feedback,in, s); -} - -void initialize(const bool feedback, const byte_t* Gc, const byte_t* Ci, const byte_t* Q, const size_t n, crypto_state s) -{ - size_t pos; - - // Reset the cipher state - memset(s,0x00,sizeof(crypto_state_t)); - - // Load in the ci (tag-nonce), together with the first half of Q (reader-nonce) - for (pos = 0; pos < 4; pos++) - { - next_n(feedback,n,Ci[2*pos ],s); - next_n(feedback,n,Ci[2*pos+1],s); - next(feedback,Q[pos],s); - } - - // Load in the diversified key (Gc), together with the second half of Q (reader-nonce) - for (pos = 0; pos < 4; pos++) - { - next_n(feedback,n,Gc[2*pos ],s); - next_n(feedback,n,Gc[2*pos+1],s); - next(feedback,Q[pos+4],s); - } -} - -byte_t cm_byte(crypto_state s) -{ - // Construct keystream byte by combining both nibbles - return nibbles_to_byte(s->b0,s->b1); -} - -byte_t sm_byte(crypto_state s) { - byte_t ks; - - // Construct keystream byte by combining 2 parts from 4 nibbles - next_n(false,2,0,s); - ks = s->b1 << 4; - next_n(false,2,0,s); - ks |= s->b1; - - return ks; -} - -void print_crypto_state(const char* text,crypto_state s) { - int pos; - - printf("%s",text); - for(pos = 6; pos >= 0; pos--) - printf(" %02x", (byte_t)(s->l >> (pos * 5)) & 0x1f); - - printf(" |"); - for(pos = 6; pos >= 0; pos--) - printf(" %02x", (byte_t)(s->m >> (pos * 7)) & 0x7f); - - printf(" |"); - for(pos = 4; pos >= 0; pos--) - printf(" %02x", (byte_t)(s->r >> (pos * 5)) & 0x1f); - - printf(" | %02x",cm_byte(s)); - printf("\n"); -} - -void sm_auth(const byte_t* Gc, const byte_t* Ci, const byte_t* Q, byte_t* Ch, byte_t* Ci_1, crypto_state s) { - size_t pos; - - initialize(false,Gc,Ci,Q,1,s); - - // Generate challange answer for Tag and Reader - for (pos=0; pos<8; pos++) { - Ci_1[pos] = sm_byte(s); - Ch[pos] = sm_byte(s); - } -} - -void cm_auth(const byte_t* Gc, const byte_t* Ci, const byte_t* Q, byte_t* Ch, byte_t* Ci_1, byte_t* Ci_2, crypto_state s) { - size_t pos; - - initialize(true,Gc,Ci,Q,3,s); - - // Construct the reader-answer (challange) - next_n(true,6,0,s); - Ch[0] = cm_byte(s); - for (pos = 1; pos < 8; pos++) - { - next_n(true,7,0,s); - Ch [pos] = cm_byte(s); - } - - // Construct the tag-answer (Ci+1 = ff .. .. .. .. .. .. ..) - Ci_1[0] = 0xff; - for (pos = 1; pos < 8; pos++) - { - next_n(true,2,0,s); - Ci_1[pos] = cm_byte(s); - } - - // Construct the session key (Ci+2) - for (pos = 0; pos < 8; pos++) - { - next_n(true,2,0,s); - Ci_2[pos] = cm_byte(s); - } - - // Prepare the cipher for encryption by shifting 3 more times - next_n(true,3,0,s); -} - -void cm_crypt(const CryptoAction ca, const byte_t offset, const byte_t len, const byte_t* in, byte_t* out, crypto_state s) { - size_t pos; - byte_t bt; - - next_n(true,5,0,s); - next(true,offset,s); - next_n(true,5,0,s); - next(true,len,s); - for (pos=0; pos. - * - */ - -#ifndef _CRYPTOLIB_H_ -#define _CRYPTOLIB_H_ - -#include "defines.h" -#include -#include -#include - -// A nibble is actually only 4 bits, but there is no such type ;) -typedef byte_t nibble; - -typedef struct { - uint64_t l; - uint64_t m; - uint64_t r; - nibble b0; - nibble b1; - nibble b1l; - nibble b1r; - nibble b1s; -}crypto_state_t; -typedef crypto_state_t* crypto_state; - -void print_crypto_state(const char* text,crypto_state s); -void sm_auth(const byte_t* Gc, const byte_t* Ci, const byte_t* Q, byte_t* Ch, byte_t* Ci_1, crypto_state s); -void cm_auth(const byte_t* Gc, const byte_t* Ci, const byte_t* Q, byte_t* Ch, byte_t* Ci_1, byte_t* Ci_2, crypto_state s); -void cm_encrypt(const byte_t offset, const byte_t len, const byte_t* pt, byte_t* ct, crypto_state s); -void cm_decrypt(const byte_t offset, const byte_t len, const byte_t* ct, byte_t* pt, crypto_state s); -void cm_grind_read_system_zone(const byte_t offset, const byte_t len, const byte_t* pt, crypto_state s); -void cm_grind_set_user_zone(const byte_t zone, crypto_state s); -void cm_mac(byte_t* mac, crypto_state s); -void cm_password(const byte_t* pt, byte_t* ct, crypto_state s); - -#endif // _CRYPTOLIB_H_ diff --git a/tools/cryptorf/defines.h b/tools/cryptorf/defines.h deleted file mode 100644 index 4962d7981..000000000 --- a/tools/cryptorf/defines.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * Defines - * - * Copyright (C) 2010, Flavio D. Garcia, Peter van Rossum, Roel Verdult - * and Ronny Wichers Schreur. Radboud University Nijmegen - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifndef _DEFINES_H_ -#define _DEFINES_H_ - -#define _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_DEPRECATE -#include -#include -#include -#include -#define null 0 -typedef unsigned char byte_t; -typedef long long unsigned int ui64; - -#endif // _DEFINES_H_ diff --git a/tools/cryptorf/laundry.sh b/tools/cryptorf/laundry.sh deleted file mode 100755 index 46fd94bfe..000000000 --- a/tools/cryptorf/laundry.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -./crf 4f794a463ff81d81 2 0 80 546dae diff --git a/tools/cryptorf/sm.c b/tools/cryptorf/sm.c index c432440e6..fde70d3a5 100644 --- a/tools/cryptorf/sm.c +++ b/tools/cryptorf/sm.c @@ -20,10 +20,16 @@ * */ -#include "defines.h" +#include +#include +#include #include "cryptolib.h" #include "util.h" -#include +#ifdef _MSC_VER + // avoid scanf warnings in Visual Studio + #define _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_DEPRECATE +#endif int main(int argc, const char* argv[]) { @@ -31,16 +37,16 @@ int main(int argc, const char* argv[]) crypto_state_t s; size_t pos; - byte_t Q[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // Reader random - byte_t Gc[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // Secret seed - byte_t Ci[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // Card random (last state) - byte_t Ch[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // Reader answer - byte_t Ci_1[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // Card answer + uint8_t Q[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // Reader random + uint8_t Gc[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // Secret seed + uint8_t Ci[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // Card random (last state) + uint8_t Ch[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // Reader answer + uint8_t Ci_1[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // Card answer // Various argument options - ui64 nGc; // Card secret - ui64 nCi; // Card random - ui64 nQ; // Reader main-random + uint64_t nGc; // Card secret + uint64_t nCi; // Card random + uint64_t nQ; // Reader main-random // Show header and help syntax printf("SecureMemory simulator - (c) Radboud University Nijmegen\n"); @@ -51,9 +57,9 @@ int main(int argc, const char* argv[]) } // Parse arguments - sscanf(argv[1],"%016llx",&nGc); num_to_bytes(nGc,8,Gc); - sscanf(argv[2],"%016llx",&nCi); num_to_bytes(nCi,8,Ci); - sscanf(argv[3],"%016llx",&nQ); num_to_bytes(nQ,8,Q); + sscanf(argv[1],"%016" SCNx64,&nGc); num_to_bytes(nGc,8,Gc); + sscanf(argv[2],"%016" SCNx64,&nCi); num_to_bytes(nCi,8,Ci); + sscanf(argv[3],"%016" SCNx64,&nQ); num_to_bytes(nQ,8,Q); // Calculate authentication sm_auth(Gc,Ci,Q,Ch,Ci_1,&s); diff --git a/tools/cryptorf/sma.cpp b/tools/cryptorf/sma.cpp index e8f1145fd..705658651 100644 --- a/tools/cryptorf/sma.cpp +++ b/tools/cryptorf/sma.cpp @@ -20,21 +20,24 @@ * * Modified Iceman, 2020 */ - -#include "defines.h" -#include "cryptolib.h" -#include "util.h" + #include -#include +#include +#include #include #include #include #include // sort, max_element, random_shuffle, remove_if, lower_bound #include // greater, bind2nd +#include "cryptolib.h" +#include "util.h" using namespace std; #ifdef _MSC_VER + // avoid scanf warnings in Visual Studio + #define _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_DEPRECATE #define inline __inline #endif @@ -125,13 +128,13 @@ typedef struct { nibble b1r; nibble b1s; bool invalid; - byte_t Gc[8]; + uint8_t Gc[8]; }cs_t; typedef cs_t* pcs; typedef struct { - byte_t addition; - byte_t out; + uint8_t addition; + uint8_t out; } lookup_entry; enum cipher_state_side { @@ -145,18 +148,18 @@ void print_cs(const char* text,pcs s) printf("%s",text); for(pos=6;pos>=0;pos--) - printf(" %02x",(byte_t)(s->l>>(pos*5))&0x1f); + printf(" %02x",(uint8_t)(s->l>>(pos*5))&0x1f); printf(" |"); for(pos=6;pos>=0;pos--) - printf(" %02x",(byte_t)(s->m>>(pos*7))&0x7f); + printf(" %02x",(uint8_t)(s->m>>(pos*7))&0x7f); printf(" |"); for(pos=4;pos>=0;pos--) - printf(" %02x",(byte_t)(s->r>>(pos*5))&0x1f); + printf(" %02x",(uint8_t)(s->r>>(pos*5))&0x1f); printf("\n"); } -static inline byte_t mod(byte_t a, byte_t m) +static inline uint8_t mod(uint8_t a, uint8_t m) { // Just return the input when this is less or equal than the modular value if (a> (n_bits - 1))) & mask; } -static inline byte_t bit_rotate_r(byte_t a, byte_t n_bits) +static inline uint8_t bit_rotate_r(uint8_t a, uint8_t n_bits) { return ((a >> 1) | ((a&1) << (n_bits - 1))); } -static byte_t lookup_left_substraction[0x400]; -static byte_t lookup_right_subtraction[0x400]; +static uint8_t lookup_left_substraction[0x400]; +static uint8_t lookup_right_subtraction[0x400]; static lookup_entry lookup_left[0x100000]; static lookup_entry lookup_right[0x8000]; -static byte_t left_addition[0x100000]; +static uint8_t left_addition[0x100000]; static inline void init_lookup_left() { - byte_t b3,b6,temp; + uint8_t b3,b6,temp; int i,index; for(i = 0; i <0x400; i++) @@ -207,7 +210,7 @@ static inline void init_lookup_left() static inline void init_lookup_right() { - byte_t b16,b18,temp; + uint8_t b16,b18,temp; int i,index; for(i = 0; i <0x400; i++) @@ -226,8 +229,8 @@ static void init_lookup_left_substraction() { for(int index = 0; index < 0x400 ; index++) { - byte_t b3 = (index >> 5 & 0x1f); - byte_t bx = (index & 0x1f); + uint8_t b3 = (index >> 5 & 0x1f); + uint8_t bx = (index & 0x1f); lookup_left_substraction[index] = bit_rotate_r(mod((bx+0x1f)-b3,0x1f),5); } } @@ -237,12 +240,12 @@ static void init_lookup_right_substraction() for(int index = 0; index < 0x400 ; index++) { int b16 = (index >>5); - byte_t bx = (index & 0x1f); + uint8_t bx = (index & 0x1f); lookup_right_subtraction[index] = mod((bx+0x1f)-b16,0x1f); } } -static inline void previous_left(byte_t in, vector *candidate_states) +static inline void previous_left(uint8_t in, vector *candidate_states) { pcs state; size_t size = candidate_states->size(); @@ -250,7 +253,7 @@ static inline void previous_left(byte_t in, vector *candidate_states) { state = &((*candidate_states)[pos]); - byte_t bx = (byte_t)((state->l >> 30) & 0x1f); + uint8_t bx = (uint8_t)((state->l >> 30) & 0x1f); unsigned b3 = (unsigned)(state->l >> 5) & 0x3e0; state->l = (state->l << 5); @@ -267,7 +270,7 @@ static inline void previous_left(byte_t in, vector *candidate_states) state->l ^= (((uint64_t)in & 0x1f) << 20); } } else { - byte_t b6 = lookup_left_substraction[b3|bx]; + uint8_t b6 = lookup_left_substraction[b3|bx]; state->l = (state->l & 0x7ffffffe0ull) | b6; state->l ^= (((uint64_t)in & 0x1f) << 20); @@ -282,7 +285,7 @@ static inline void previous_left(byte_t in, vector *candidate_states) } } -static inline void previous_right(byte_t in, vector *candidate_states) +static inline void previous_right(uint8_t in, vector *candidate_states) { pcs state; size_t size = candidate_states->size(); @@ -290,7 +293,7 @@ static inline void previous_right(byte_t in, vector *candidate_states) { state = &((*candidate_states)[pos]); - byte_t bx = (byte_t)((state->r >> 20) & 0x1f); + uint8_t bx = (uint8_t)((state->r >> 20) & 0x1f); unsigned b16 = (unsigned)(state->r & 0x3e0);//(state->buffer_r >> 10) & 0x1f; state->r = (state->r << 5); @@ -307,7 +310,7 @@ static inline void previous_right(byte_t in, vector *candidate_states) state->r ^= (((uint64_t)in & 0xf8) << 12); } } else{ - byte_t b18 = lookup_right_subtraction[b16|bx]; + uint8_t b18 = lookup_right_subtraction[b16|bx]; state->r = (state->r & 0x1ffffe0ull) | b18; state->r ^= (((uint64_t)in & 0xf8) << 12); //state->b_right = ((b14^b17) & 0x0f); @@ -323,7 +326,7 @@ static inline void previous_right(byte_t in, vector *candidate_states) } } -static inline byte_t next_left_fast(byte_t in, uint64_t* left) +static inline uint8_t next_left_fast(uint8_t in, uint64_t* left) { if (in) *left ^= ((in & 0x1f) << 20); lookup_entry* lookup = &(lookup_left[((*left) & 0xf801f)]); @@ -331,10 +334,10 @@ static inline byte_t next_left_fast(byte_t in, uint64_t* left) return lookup->out; } -static inline byte_t next_left_ksbyte(uint64_t* left) +static inline uint8_t next_left_ksbyte(uint64_t* left) { lookup_entry* lookup; - byte_t bt; + uint8_t bt; *left = (((*left) >> 5)| ((uint64_t)left_addition[((*left) & 0xf801f)] << 30)); lookup = &(lookup_left[((*left) & 0xf801f)]); @@ -347,7 +350,7 @@ static inline byte_t next_left_ksbyte(uint64_t* left) return bt; } -static inline byte_t next_right_fast(byte_t in, uint64_t* right) +static inline uint8_t next_right_fast(uint8_t in, uint64_t* right) { if (in) *right ^= ((in&0xf8) << 12); lookup_entry* lookup = &(lookup_right[((*right) & 0x7c1f)]); @@ -355,10 +358,10 @@ static inline byte_t next_right_fast(byte_t in, uint64_t* right) return lookup->out; } -static inline void sm_left_mask(const byte_t* ks, byte_t* mask, uint64_t rstate) +static inline void sm_left_mask(const uint8_t* ks, uint8_t* mask, uint64_t rstate) { size_t pos; - byte_t bt; + uint8_t bt; for (pos=0; pos<16; pos++) { @@ -375,14 +378,14 @@ static inline void sm_left_mask(const byte_t* ks, byte_t* mask, uint64_t rstate) } } -static inline uint32_t sm_right(const byte_t* ks, byte_t* mask, vector* pcrstates) +static inline uint32_t sm_right(const uint8_t* ks, uint8_t* mask, vector* pcrstates) { - byte_t tmp_mask[16]; + uint8_t tmp_mask[16]; size_t pos,bits,bit,topbits; uint64_t rstate,counter; map bincstates; map::iterator it; - byte_t bt; + uint8_t bt; topbits = 0; for (counter=0; counter<0x2000000; counter++) @@ -452,7 +455,7 @@ static inline uint32_t sm_right(const byte_t* ks, byte_t* mask, vector static inline void previous_all_input(vector *pcstates, uint32_t gc_byte_index, cipher_state_side css) { - byte_t btGc,in; + uint8_t btGc,in; vector ncstates; vector prev_ncstates; vector::iterator it,itnew; @@ -489,7 +492,7 @@ static inline void previous_all_input(vector *pcstates, uint32_t gc_byte_i *pcstates = prev_ncstates; } -static inline void search_gc_candidates_right(const uint64_t rstate_before_gc, const uint64_t rstate_after_gc, const byte_t* Q, vector* pcstates) +static inline void search_gc_candidates_right(const uint64_t rstate_before_gc, const uint64_t rstate_after_gc, const uint8_t* Q, vector* pcstates) { vector::iterator it; vector csl_cand; @@ -556,14 +559,14 @@ static inline void search_gc_candidates_right(const uint64_t rstate_before_gc, c } } -static inline void sm_left(const byte_t* ks, byte_t* mask, vector* pcstates) +static inline void sm_left(const uint8_t* ks, uint8_t* mask, vector* pcstates) { map bincstates; map::iterator it; uint64_t counter,lstate; size_t pos,bits,bit; - byte_t correct_bits[16]; - byte_t bt; + uint8_t correct_bits[16]; + uint8_t bt; cs_t state; lookup_entry* lookup; @@ -645,7 +648,7 @@ static inline void sm_left(const byte_t* ks, byte_t* mask, vector* pcstate reverse(pcstates->begin(),pcstates->end()); } -static inline void search_gc_candidates_left(const uint64_t lstate_before_gc, const byte_t* Q, vector* pcstates) +static inline void search_gc_candidates_left(const uint64_t lstate_before_gc, const uint8_t* Q, vector* pcstates) { vector csl_cand,csl_search; vector::iterator itsearch,itcand; @@ -778,31 +781,31 @@ int main(int argc, const char* argv[]) vector::iterator it; uint32_t rbits; -// byte_t Gc[ 8] = {0x4f,0x79,0x4a,0x46,0x3f,0xf8,0x1d,0x81}; -// byte_t Gc[ 8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; -// byte_t Ci[ 8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; -// byte_t Q[ 8] = {0x12,0x34,0x56,0x78,0x12,0x34,0x56,0x78}; - byte_t Gc[ 8]; - byte_t Ci[ 8]; - byte_t Q[ 8]; - byte_t Ch[ 8]; - byte_t Ci_1[ 8]; +// uint8_t Gc[ 8] = {0x4f,0x79,0x4a,0x46,0x3f,0xf8,0x1d,0x81}; +// uint8_t Gc[ 8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; +// uint8_t Ci[ 8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; +// uint8_t Q[ 8] = {0x12,0x34,0x56,0x78,0x12,0x34,0x56,0x78}; + uint8_t Gc[ 8]; + uint8_t Ci[ 8]; + uint8_t Q[ 8]; + uint8_t Ch[ 8]; + uint8_t Ci_1[ 8]; - byte_t Gc_chk[ 8]; - byte_t Ch_chk[ 8]; - byte_t Ci_1_chk[ 8]; + uint8_t Gc_chk[ 8]; + uint8_t Ch_chk[ 8]; + uint8_t Ci_1_chk[ 8]; - // byte_t ks[16] = {0xde,0x88,0xc2,0xc9,0xee,0xd4,0x1b,0x46,0x1c,0x6a,0x92,0x50,0x76,0x1a,0xe9,0x87}; - // byte_t mask[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - // byte_t mask[16] = {0x04,0xb0,0xe1,0x10,0xc0,0x33,0x44,0x20,0x20,0x00,0x70,0x8c,0x22,0x04,0x10,0x80}; + // uint8_t ks[16] = {0xde,0x88,0xc2,0xc9,0xee,0xd4,0x1b,0x46,0x1c,0x6a,0x92,0x50,0x76,0x1a,0xe9,0x87}; + // uint8_t mask[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + // uint8_t mask[16] = {0x04,0xb0,0xe1,0x10,0xc0,0x33,0x44,0x20,0x20,0x00,0x70,0x8c,0x22,0x04,0x10,0x80}; - byte_t ks[16]; - byte_t mask[16]; + uint8_t ks[16]; + uint8_t mask[16]; - ui64 nCi; // Card random - ui64 nQ; // Reader random - ui64 nCh; // Reader challange - ui64 nCi_1; // Card anwser + uint64_t nCi; // Card random + uint64_t nQ; // Reader random + uint64_t nCh; // Reader challange + uint64_t nCi_1; // Card anwser if ((argc != 2) && (argc != 5)) { @@ -818,7 +821,7 @@ int main(int argc, const char* argv[]) if (argc == 2) { // Generate random values for the key and randoms - srand((uint32_t)time(null)); + srand((uint32_t)time(NULL)); for (pos = 0; pos<8; pos++) { Gc[pos] = rand(); @@ -828,10 +831,10 @@ int main(int argc, const char* argv[]) sm_auth(Gc,Ci,Q,Ch,Ci_1,&ostate); printf(" Gc: "); print_bytes(Gc,8); } else { - sscanf(argv[1],"%016llx",&nCi); num_to_bytes(nCi,8,Ci); - sscanf(argv[2],"%016llx",&nQ); num_to_bytes(nQ,8,Q); - sscanf(argv[3],"%016llx",&nCh); num_to_bytes(nCh,8,Ch); - sscanf(argv[4],"%016llx",&nCi_1); num_to_bytes(nCi_1,8,Ci_1); + sscanf(argv[1],"%016" SCNx64,&nCi); num_to_bytes(nCi,8,Ci); + sscanf(argv[2],"%016" SCNx64,&nQ); num_to_bytes(nQ,8,Q); + sscanf(argv[3],"%016" SCNx64,&nCh); num_to_bytes(nCh,8,Ch); + sscanf(argv[4],"%016" SCNx64,&nCi_1); num_to_bytes(nCi_1,8,Ci_1); printf(" Gc: unknown\n"); } @@ -883,7 +886,7 @@ int main(int argc, const char* argv[]) { rstate_after_gc = *itrstates; sm_left_mask(ks,mask,rstate_after_gc); - printf("Using the state from the top-right bin: " _YELLOW_("0x%07llx")"\n",(unsigned long long)rstate_after_gc); + printf("Using the state from the top-right bin: " _YELLOW_("0x%07" PRIx64)"\n",rstate_after_gc); search_gc_candidates_right(rstate_before_gc,rstate_after_gc,Q,&crstates); printf("Found " _YELLOW_("%lu")" right candidates using the meet-in-the-middle attack\n",crstates.size()); @@ -908,7 +911,7 @@ int main(int argc, const char* argv[]) sm_auth(Gc_chk,Ci,Q,Ch_chk,Ci_1_chk,&ostate); if ((memcmp(Ch_chk,Ch,8) == 0) && (memcmp(Ci_1_chk,Ci_1,8) == 0)) { - printf("\nFound valid key: " _GREEN_("%016llX")"\n\n",(unsigned long long)*itgc); + printf("\nFound valid key: " _GREEN_("%016" PRIx64)"\n\n",*itgc); return 0; } } diff --git a/tools/cryptorf/sma_multi.cpp b/tools/cryptorf/sma_multi.cpp index 5c05e2e04..d3658ff23 100644 --- a/tools/cryptorf/sma_multi.cpp +++ b/tools/cryptorf/sma_multi.cpp @@ -20,12 +20,10 @@ * * Modifed Iceman, 2020 */ - -#include "defines.h" -#include "cryptolib.h" -#include "util.h" + #include -#include +#include +#include #include #include #include @@ -34,9 +32,15 @@ #include // std::thread #include #include +#include "cryptolib.h" +#include "util.h" + using namespace std; #ifdef _MSC_VER + // avoid scanf warnings in Visual Studio + #define _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_DEPRECATE #define inline __inline #endif @@ -127,13 +131,13 @@ typedef struct { nibble b1r; nibble b1s; bool invalid; - byte_t Gc[8]; + uint8_t Gc[8]; }cs_t; typedef cs_t* pcs; typedef struct { - byte_t addition; - byte_t out; + uint8_t addition; + uint8_t out; } lookup_entry; enum cipher_state_side { @@ -147,21 +151,21 @@ void print_cs(const char* text,pcs s) { printf("%s",text); for(pos=6;pos>=0;pos--) - printf(" %02x",(byte_t)(s->l>>(pos*5))&0x1f); + printf(" %02x",(uint8_t)(s->l>>(pos*5))&0x1f); printf(" |"); for(pos=6;pos>=0;pos--) - printf(" %02x",(byte_t)(s->m>>(pos*7))&0x7f); + printf(" %02x",(uint8_t)(s->m>>(pos*7))&0x7f); printf(" |"); for(pos=4;pos>=0;pos--) - printf(" %02x",(byte_t)(s->r>>(pos*5))&0x1f); + printf(" %02x",(uint8_t)(s->r>>(pos*5))&0x1f); printf("\n"); } -static inline byte_t mod(byte_t a, byte_t m) { +static inline uint8_t mod(uint8_t a, uint8_t m) { // Just return the input when this is less or equal than the modular value if (a> (n_bits - 1))) & mask; } -static inline byte_t bit_rotate_r(byte_t a, byte_t n_bits) { +static inline uint8_t bit_rotate_r(uint8_t a, uint8_t n_bits) { return ((a >> 1) | ((a&1) << (n_bits - 1))); } */ @@ -189,14 +193,14 @@ static inline byte_t bit_rotate_r(byte_t a, byte_t n_bits) { #define BIT_ROR(a) (((a) >> 1) | (((a) & 1) << 4)) -static byte_t lookup_left_substraction[0x400]; -static byte_t lookup_right_subtraction[0x400]; +static uint8_t lookup_left_substraction[0x400]; +static uint8_t lookup_right_subtraction[0x400]; static lookup_entry lookup_left[0x100000]; static lookup_entry lookup_right[0x8000]; -static byte_t left_addition[0x100000]; +static uint8_t left_addition[0x100000]; static inline void init_lookup_left() { - byte_t b3, b6, temp; + uint8_t b3, b6, temp; int i, index; for (i = 0; i <0x400; i++){ @@ -215,7 +219,7 @@ static inline void init_lookup_left() { } static inline void init_lookup_right() { - byte_t b16, b18, temp; + uint8_t b16, b18, temp; int i, index; for(i = 0; i <0x400; i++) { @@ -231,8 +235,8 @@ static inline void init_lookup_right() { static void init_lookup_left_substraction() { for(int index = 0; index < 0x400 ; index++) { - byte_t b3 = (index >> 5 & 0x1f); - byte_t bx = (index & 0x1f); + uint8_t b3 = (index >> 5 & 0x1f); + uint8_t bx = (index & 0x1f); //lookup_left_substraction[index] = bit_rotate_r(mod((bx+0x1f)-b3,0x1f),5); lookup_left_substraction[index] = BIT_ROR( mod((bx + 0x1F) - b3, 0x1F)); @@ -242,18 +246,18 @@ static void init_lookup_left_substraction() { static void init_lookup_right_substraction() { for(int index = 0; index < 0x400 ; index++) { int b16 = (index >>5); - byte_t bx = (index & 0x1f); + uint8_t bx = (index & 0x1f); lookup_right_subtraction[index] = mod((bx + 0x1F) - b16, 0x1F); } } -static inline void previous_left(byte_t in, vector *candidate_states) { +static inline void previous_left(uint8_t in, vector *candidate_states) { pcs state; size_t size = candidate_states->size(); for(size_t pos=0; posl >> 30) & 0x1f); + uint8_t bx = (uint8_t)((state->l >> 30) & 0x1f); unsigned b3 = (unsigned)(state->l >> 5) & 0x3e0; state->l = (state->l << 5); @@ -268,7 +272,7 @@ static inline void previous_left(byte_t in, vector *candidate_states) { state->l ^= (((uint64_t)in & 0x1f) << 20); } } else { - byte_t b6 = lookup_left_substraction[b3|bx]; + uint8_t b6 = lookup_left_substraction[b3|bx]; state->l = (state->l & 0x7ffffffe0ull) | b6; state->l ^= (((uint64_t)in & 0x1f) << 20); @@ -282,13 +286,13 @@ static inline void previous_left(byte_t in, vector *candidate_states) { } } -static inline void previous_right(byte_t in, vector *candidate_states) { +static inline void previous_right(uint8_t in, vector *candidate_states) { pcs state; size_t size = candidate_states->size(); for(size_t pos=0; posr >> 20) & 0x1f); + uint8_t bx = (uint8_t)((state->r >> 20) & 0x1f); unsigned b16 = (unsigned)(state->r & 0x3e0);//(state->buffer_r >> 10) & 0x1f; state->r = (state->r << 5); @@ -303,7 +307,7 @@ static inline void previous_right(byte_t in, vector *candidate_states) { state->r ^= (((uint64_t)in & 0xf8) << 12); } } else { - byte_t b18 = lookup_right_subtraction[b16|bx]; + uint8_t b18 = lookup_right_subtraction[b16|bx]; state->r = (state->r & 0x1ffffe0ull) | b18; state->r ^= (((uint64_t)in & 0xf8) << 12); //state->b_right = ((b14^b17) & 0x0f); @@ -318,7 +322,7 @@ static inline void previous_right(byte_t in, vector *candidate_states) { } } -static inline byte_t next_left_fast(byte_t in, uint64_t* left) { +static inline uint8_t next_left_fast(uint8_t in, uint64_t* left) { if (in) *left ^= ((in & 0x1f) << 20); @@ -327,9 +331,9 @@ static inline byte_t next_left_fast(byte_t in, uint64_t* left) { return lookup->out; } -static inline byte_t next_left_ksbyte(uint64_t* left) { +static inline uint8_t next_left_ksbyte(uint64_t* left) { lookup_entry* lookup; - byte_t bt; + uint8_t bt; *left = (((*left) >> 5)| ((uint64_t)left_addition[((*left) & 0xf801f)] << 30)); lookup = &(lookup_left[((*left) & 0xf801f)]); @@ -342,17 +346,17 @@ static inline byte_t next_left_ksbyte(uint64_t* left) { return bt; } -static inline byte_t next_right_fast(byte_t in, uint64_t* right) { +static inline uint8_t next_right_fast(uint8_t in, uint64_t* right) { if (in) *right ^= ((in&0xf8) << 12); lookup_entry* lookup = &(lookup_right[((*right) & 0x7c1f)]); *right = (((*right) >> 5) | (lookup->addition << 20)); return lookup->out; } -static inline void sm_left_mask(const byte_t* ks, byte_t* mask, uint64_t rstate) { +static inline void sm_left_mask(const uint8_t* ks, uint8_t* mask, uint64_t rstate) { for (uint8_t pos = 0; pos < 16; pos++) { next_right_fast(0,&rstate); - byte_t bt = next_right_fast(0,&rstate) << 4; + uint8_t bt = next_right_fast(0,&rstate) << 4; next_right_fast(0,&rstate); bt |= next_right_fast(0,&rstate); @@ -375,13 +379,13 @@ uint32_t g_num_cpus = std::thread::hardware_concurrency(); static void ice_sm_right_thread( uint8_t offset, uint8_t skips, - const byte_t* ks, + const uint8_t* ks, map* bincstates, - byte_t* mask + uint8_t* mask ) { - byte_t tmp_mask[16]; - byte_t bt; + uint8_t tmp_mask[16]; + uint8_t bt; for (uint64_t counter = offset; counter < 0x2000000; counter += skips) { // Reset the current bitcount of correct bits @@ -444,7 +448,7 @@ static void ice_sm_right_thread( } } } -static uint32_t ice_sm_right(const byte_t* ks, byte_t* mask, vector* pcrstates) { +static uint32_t ice_sm_right(const uint8_t* ks, uint8_t* mask, vector* pcrstates) { uint32_t g_num_cpus = std::thread::hardware_concurrency(); map bincstates; @@ -478,14 +482,14 @@ static uint32_t ice_sm_right(const byte_t* ks, byte_t* mask, vector* p static void ice_sm_left_thread( uint8_t offset, uint8_t skips, - const byte_t* ks, + const uint8_t* ks, map* bincstates, - byte_t* mask + uint8_t* mask ) { size_t pos, bits; - byte_t correct_bits[16]; - byte_t bt; + uint8_t correct_bits[16]; + uint8_t bt; lookup_entry* lookup; // Reset and initialize the cryptostate and vector @@ -561,7 +565,7 @@ static void ice_sm_left_thread( } } -static void ice_sm_left(const byte_t* ks, byte_t* mask, vector* pcstates) { +static void ice_sm_left(const uint8_t* ks, uint8_t* mask, vector* pcstates) { uint32_t g_num_cpus = std::thread::hardware_concurrency(); @@ -589,12 +593,12 @@ static void ice_sm_left(const byte_t* ks, byte_t* mask, vector* pcstates) reverse(pcstates->begin(), pcstates->end()); } -static inline uint32_t sm_right(const byte_t* ks, byte_t* mask, vector* pcrstates) { - byte_t tmp_mask[16]; +static inline uint32_t sm_right(const uint8_t* ks, uint8_t* mask, vector* pcrstates) { + uint8_t tmp_mask[16]; size_t pos, bits, bit, topbits; map bincstates; map::iterator it; - byte_t bt; + uint8_t bt; topbits = 0; @@ -658,7 +662,7 @@ static inline uint32_t sm_right(const byte_t* ks, byte_t* mask, vector } static inline void previous_all_input(vector *pcstates, uint32_t gc_byte_index, cipher_state_side css) { - byte_t btGc,in; + uint8_t btGc,in; vector ncstates; vector prev_ncstates; vector::iterator it,itnew; @@ -691,7 +695,7 @@ static inline void previous_all_input(vector *pcstates, uint32_t gc_byte_i *pcstates = prev_ncstates; } -static inline void search_gc_candidates_right(const uint64_t rstate_before_gc, const uint64_t rstate_after_gc, const byte_t* Q, vector* pcstates) { +static inline void search_gc_candidates_right(const uint64_t rstate_before_gc, const uint64_t rstate_after_gc, const uint8_t* Q, vector* pcstates) { vector::iterator it; vector csl_cand; map matchbox; @@ -743,13 +747,13 @@ static inline void search_gc_candidates_right(const uint64_t rstate_before_gc, c } } -static inline void sm_left(const byte_t* ks, byte_t* mask, vector* pcstates) { +static inline void sm_left(const uint8_t* ks, uint8_t* mask, vector* pcstates) { map bincstates; map::iterator it; uint64_t counter, lstate; size_t pos, bits; - byte_t correct_bits[16]; - byte_t bt; + uint8_t correct_bits[16]; + uint8_t bt; cs_t state; lookup_entry* lookup; @@ -831,7 +835,7 @@ static inline void sm_left(const byte_t* ks, byte_t* mask, vector* pcstate reverse(pcstates->begin(), pcstates->end()); } -static inline void search_gc_candidates_left(const uint64_t lstate_before_gc, const byte_t* Q, vector* pcstates) { +static inline void search_gc_candidates_left(const uint64_t lstate_before_gc, const uint8_t* Q, vector* pcstates) { vector csl_cand,csl_search; vector::iterator itsearch,itcand; map matchbox; @@ -937,14 +941,14 @@ static void ice_compare( uint8_t skips, vector* candidates, crypto_state_t* ostate, - byte_t *Ci, - byte_t *Q, - byte_t *Ch, - byte_t *Ci_1 + uint8_t *Ci, + uint8_t *Q, + uint8_t *Ch, + uint8_t *Ci_1 ) { - byte_t Gc_chk[8]; - byte_t Ch_chk[ 8]; - byte_t Ci_1_chk[ 8]; + uint8_t Gc_chk[8]; + uint8_t Ch_chk[ 8]; + uint8_t Ci_1_chk[ 8]; for (std::size_t i = offset; i < candidates->size(); i += skips) { if (key_found.load(std::memory_order_relaxed)) @@ -976,27 +980,27 @@ int main(int argc, const char* argv[]) { vector::iterator it; uint32_t rbits; - // byte_t Gc[ 8] = {0x4f,0x79,0x4a,0x46,0x3f,0xf8,0x1d,0x81}; - // byte_t Gc[ 8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - // byte_t Ci[ 8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; - // byte_t Q[ 8] = {0x12,0x34,0x56,0x78,0x12,0x34,0x56,0x78}; - byte_t Gc[ 8]; - byte_t Ci[ 8]; - byte_t Q[ 8]; - byte_t Ch[ 8]; - byte_t Ci_1[ 8]; + // uint8_t Gc[ 8] = {0x4f,0x79,0x4a,0x46,0x3f,0xf8,0x1d,0x81}; + // uint8_t Gc[ 8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + // uint8_t Ci[ 8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; + // uint8_t Q[ 8] = {0x12,0x34,0x56,0x78,0x12,0x34,0x56,0x78}; + uint8_t Gc[ 8]; + uint8_t Ci[ 8]; + uint8_t Q[ 8]; + uint8_t Ch[ 8]; + uint8_t Ci_1[ 8]; - // byte_t ks[16] = {0xde,0x88,0xc2,0xc9,0xee,0xd4,0x1b,0x46,0x1c,0x6a,0x92,0x50,0x76,0x1a,0xe9,0x87}; - // byte_t mask[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - // byte_t mask[16] = {0x04,0xb0,0xe1,0x10,0xc0,0x33,0x44,0x20,0x20,0x00,0x70,0x8c,0x22,0x04,0x10,0x80}; + // uint8_t ks[16] = {0xde,0x88,0xc2,0xc9,0xee,0xd4,0x1b,0x46,0x1c,0x6a,0x92,0x50,0x76,0x1a,0xe9,0x87}; + // uint8_t mask[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + // uint8_t mask[16] = {0x04,0xb0,0xe1,0x10,0xc0,0x33,0x44,0x20,0x20,0x00,0x70,0x8c,0x22,0x04,0x10,0x80}; - byte_t ks[16]; - byte_t mask[16]; + uint8_t ks[16]; + uint8_t mask[16]; - ui64 nCi; // Card random - ui64 nQ; // Reader random - ui64 nCh; // Reader challange - ui64 nCi_1; // Card anwser + uint64_t nCi; // Card random + uint64_t nQ; // Reader random + uint64_t nCh; // Reader challange + uint64_t nCi_1; // Card anwser if ((argc != 2) && (argc != 5)) { printf("SecureMemory recovery - (c) Radboud University Nijmegen\n\n"); @@ -1010,7 +1014,7 @@ int main(int argc, const char* argv[]) { // Check if this is a simulation if (argc == 2) { // Generate random values for the key and randoms - srand((uint32_t)time(null)); + srand((uint32_t)time(NULL)); for (pos = 0; pos<8; pos++) { Gc[pos] = rand(); Ci[pos] = rand(); @@ -1019,10 +1023,10 @@ int main(int argc, const char* argv[]) { sm_auth(Gc,Ci,Q,Ch,Ci_1,&ostate); printf(" Gc: "); print_bytes(Gc,8); } else { - sscanf(argv[1],"%016llx",&nCi); num_to_bytes(nCi,8,Ci); - sscanf(argv[2],"%016llx",&nQ); num_to_bytes(nQ,8,Q); - sscanf(argv[3],"%016llx",&nCh); num_to_bytes(nCh,8,Ch); - sscanf(argv[4],"%016llx",&nCi_1); num_to_bytes(nCi_1,8,Ci_1); + sscanf(argv[1],"%016" SCNx64,&nCi); num_to_bytes(nCi,8,Ci); + sscanf(argv[2],"%016" SCNx64,&nQ); num_to_bytes(nQ,8,Q); + sscanf(argv[3],"%016" SCNx64,&nCh); num_to_bytes(nCh,8,Ch); + sscanf(argv[4],"%016" SCNx64,&nCi_1); num_to_bytes(nCi_1,8,Ci_1); printf(" Gc: unknown\n"); } @@ -1080,7 +1084,7 @@ int main(int argc, const char* argv[]) { for (itrstates = rstates.begin(); itrstates != rstates.end(); ++itrstates) { rstate_after_gc = *itrstates; sm_left_mask(ks, mask, rstate_after_gc); - printf("Using the state from the top-right bin: " _YELLOW_("0x%07llx")"\n", (unsigned long long)rstate_after_gc); + printf("Using the state from the top-right bin: " _YELLOW_("0x%07" PRIx64)"\n", rstate_after_gc); search_gc_candidates_right(rstate_before_gc, rstate_after_gc, Q, &crstates); printf("Found " _YELLOW_("%lu")" right candidates using the meet-in-the-middle attack\n", crstates.size()); diff --git a/tools/cryptorf/util.c b/tools/cryptorf/util.c index 4da252ab5..383991b96 100644 --- a/tools/cryptorf/util.c +++ b/tools/cryptorf/util.c @@ -1,20 +1,20 @@ -#include "util.h" #include +#include "util.h" -void num_to_bytes(uint64_t n, size_t len, byte_t* dst) +void num_to_bytes(uint64_t n, size_t len, uint8_t *dst) { - while (len--) - { - dst[len] = (byte_t)n; + while (len--) { + dst[len] = (uint8_t)n; n >>= 8; } } -void print_bytes(const byte_t* pbtData, const size_t szLen) { +void print_bytes(const uint8_t *pbtData, const size_t szLen) +{ size_t uiPos; - for (uiPos=0; uiPos < szLen; uiPos++) { - printf("%02x ",pbtData[uiPos]); - if (uiPos>20){ + for (uiPos = 0; uiPos < szLen; uiPos++) { + printf("%02x ", pbtData[uiPos]); + if (uiPos > 20) { printf("..."); break; } diff --git a/tools/cryptorf/util.h b/tools/cryptorf/util.h index 68a16ecf1..844f3e954 100644 --- a/tools/cryptorf/util.h +++ b/tools/cryptorf/util.h @@ -1,9 +1,9 @@ /* - * + * * Various Utilities * * Copyright (C) 2010, Flavio D. Garcia, Peter van Rossum, Roel Verdult - * and Ronny Wichers Schreur. Radboud University Nijmegen + * and Ronny Wichers Schreur. Radboud University Nijmegen * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,15 +17,17 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * + * */ #ifndef _UTIL_H_ #define _UTIL_H_ -#include -#include "defines.h" +#ifdef __cplusplus +extern "C" { +#endif +#include #define AEND "\x1b[0m" @@ -37,7 +39,10 @@ #define _CYAN_(s) "\x1b[36m" s AEND #define _WHITE_(s) "\x1b[37m" s AEND -void num_to_bytes(uint64_t n, size_t len, byte_t* dst); -void print_bytes(const byte_t* pbtData, const size_t szLen); +void num_to_bytes(uint64_t n, size_t len, uint8_t *dst); +void print_bytes(const uint8_t *pbtData, const size_t szLen); +#ifdef __cplusplus +} +#endif #endif // _UTIL_H_