From 7401d51ebf256b723e10e3db875feafaefe01c5c Mon Sep 17 00:00:00 2001
From: merlokk <807634+merlokk@users.noreply.github.com>
Date: Fri, 28 Dec 2018 20:33:24 +0200
Subject: [PATCH] roca works

---
 client/emv/cmdemv.c   | 15 ++---------
 client/emv/emv_roca.c | 58 +++++++++++++++++++++++++++++++++++++++----
 client/emv/emv_roca.h |  7 ++----
 3 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c
index adb47b136..4cbbe2e0b 100644
--- a/client/emv/cmdemv.c
+++ b/client/emv/cmdemv.c
@@ -1661,26 +1661,15 @@ int CmdEMVRoca(const char *cmd) {
 		
 		PrintAndLogEx(INFO, "ICC pk modulus: %s", sprint_hex_inrow(icc_pk->modulus, icc_pk->mlen));
 		
-		
-		uint8_t key[] = "\x94\x4e\x13\x20\x8a\x28\x0c\x37\xef\xc3\x1c\x31\x14\x48\x5e\x59"\
-		                "\x01\x92\xad\xbb\x8e\x11\xc8\x7c\xad\x60\xcd\xef\x00\x37\xce\x99"\
-						"\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\
-						"\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7";
-		PrintAndLogEx(INFO, "DEMO ICC pk modulus: %s", sprint_hex_inrow(key, 64));
-		if (emv_rocacheck(key, 64)) 
-				PrintAndLogEx(INFO, "DEMO ICC pk is vulnerable by roca.");
-		
-		
 		//	icc_pk->exp, icc_pk->elen
 		//	icc_pk->modulus, icc_pk->mlen
 		if (icc_pk->elen > 0 && icc_pk->mlen > 0) {
-			if (emv_rocacheck(icc_pk->modulus, icc_pk->mlen)) {
+			if (emv_rocacheck(icc_pk->modulus, icc_pk->mlen, true)) {
 				PrintAndLogEx(INFO, "ICC pk is a subject to ROCA vulnerability, insecure..");
 			} else {
 				PrintAndLogEx(INFO, "ICC pk is OK(");
 			}
-		}
-		
+		}		
 		
 		PKISetStrictExecution(true);
 	}
diff --git a/client/emv/emv_roca.c b/client/emv/emv_roca.c
index 977584f73..5081ed446 100644
--- a/client/emv/emv_roca.c
+++ b/client/emv/emv_roca.c
@@ -82,12 +82,12 @@ void print_mpi(const char *msg, int radix, const mbedtls_mpi *X) {
 	printf("%s[%d] %s\n", msg, len, Xchar);	
 }
 
-bool emv_rocacheck(const unsigned char *buf, size_t buflen) {
+bool emv_rocacheck(const unsigned char *buf, size_t buflen, bool verbose) {
 
 	mbedtls_mpi t_modulus;
 	mbedtls_mpi_init(&t_modulus);
 
-	bool ret = true;
+	bool ret = false;
 
 	rocacheck_init();
 
@@ -112,8 +112,8 @@ bool emv_rocacheck(const unsigned char *buf, size_t buflen) {
 		MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(&g_one, mpi_get_uint(&t_temp)) );
 		
 		if (bitand_is_zero(&g_one, &g_prints[i])) {
-			PrintAndLogEx(FAILED, "No fingerprint found.\n");
-			ret = false;
+			if (verbose)
+				PrintAndLogEx(FAILED, "No fingerprint found.\n");
 			goto cleanup;
 		}
 		
@@ -122,7 +122,9 @@ bool emv_rocacheck(const unsigned char *buf, size_t buflen) {
 		mbedtls_mpi_free(&t_prime);
 	}
 
-	PrintAndLogEx(SUCCESS, "Fingerprint found!\n");
+	ret = true;
+	if (verbose)
+		PrintAndLogEx(SUCCESS, "Fingerprint found!\n");
 
 cleanup:
 	mbedtls_mpi_free(&t_modulus);
@@ -130,3 +132,49 @@ cleanup:
 	rocacheck_cleanup();
 	return ret;
 }
+
+int roca_self_test( int verbose ) {
+	int ret = 0;
+
+	if( verbose != 0 )
+		printf( "\nROCA check vulnerability tests\n" );
+
+	// positive
+	uint8_t keyp[] = "\x94\x4e\x13\x20\x8a\x28\x0c\x37\xef\xc3\x1c\x31\x14\x48\x5e\x59"\
+	                "\x01\x92\xad\xbb\x8e\x11\xc8\x7c\xad\x60\xcd\xef\x00\x37\xce\x99"\
+					"\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\
+					"\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7";
+
+	if( verbose != 0 )
+		printf( "  ROCA positive test: " );
+	
+	if (emv_rocacheck(keyp, 64, false)) {
+		if( verbose != 0 )
+			printf( "passed\n" );
+	} else {
+		ret = 1;
+		if( verbose != 0 )
+			printf( "failed\n" );
+	}
+
+	// negative
+	uint8_t keyn[] = "\x84\x4e\x13\x20\x8a\x28\x0c\x37\xef\xc3\x1c\x31\x14\x48\x5e\x59"\
+	                "\x01\x92\xad\xbb\x8e\x11\xc8\x7c\xad\x60\xcd\xef\x00\x37\xce\x99"\
+					"\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\
+					"\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7";
+
+	if( verbose != 0 )
+		printf( "  ROCA negative test: " );
+
+	if (emv_rocacheck(keyn, 64, false)) {
+		ret = 1;
+		if( verbose != 0 )
+			printf( "failed\n" );
+	} else {
+		if( verbose != 0 )
+			printf( "passed\n" );
+	}
+
+	
+	return ret;
+}
diff --git a/client/emv/emv_roca.h b/client/emv/emv_roca.h
index a42d8349e..a9559ef79 100644
--- a/client/emv/emv_roca.h
+++ b/client/emv/emv_roca.h
@@ -31,11 +31,8 @@
 
 #define ROCA_PRINTS_LENGTH	17
 
-void rocacheck_init(void);
-void rocacheck_cleanup(void);
-int bitand_is_zero(	mbedtls_mpi* a, mbedtls_mpi* b );
-
-extern bool emv_rocacheck( const unsigned char *buf, size_t buflen );
+extern bool emv_rocacheck( const unsigned char *buf, size_t buflen, bool verbose );
+extern int roca_self_test( int verbose );
 
 #endif