From 03006df71d07c88b1fd9f01839336801207b7ec4 Mon Sep 17 00:00:00 2001
From: hackbard <hackbard>
Date: Thu, 23 Mar 2006 15:23:22 +0000
Subject: [PATCH] first beta - patch sent to librfid list

---
 gemtag/gemtag.c | 62 +++++++++++++++++++++----------------------------
 gemtag/gemtag.h |  8 ++++++-
 2 files changed, 34 insertions(+), 36 deletions(-)

diff --git a/gemtag/gemtag.c b/gemtag/gemtag.c
index 121170f..e674d49 100644
--- a/gemtag/gemtag.c
+++ b/gemtag/gemtag.c
@@ -1,5 +1,6 @@
 /*
- *  (C) 2006 by Frank Zirkelbach <hackbard@hackdaworld.org>
+ *  (C) 2006 by Harald Welte <laforge@gnumonks.org>
+ *              Frank Zirkelbach <hackbard@hackdaworld.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 
@@ -25,21 +26,20 @@
 #include "gemtag.h"
 
 int asciidump(unsigned char *data,int len) {
+
 	int i;
 
 	for(i=0;i<len;i++)
-		if((data[i]>0x19)&&(data[i]<0x7f)) printf("%c",data[i]);
-		else printf(".");
-	//printf("\n");
+		printf("%c",(data[i]>0x19)&&(data[i]<0x7f)?data[i]:'.');
 
 	return 0;
 }
 
 int hexdump(unsigned char *data,int len) {
+
 	int i;
 
 	for(i=0;i<len;i++) printf("%02x ",data[i]);
-	//printf("\n");
 
 	return 0;
 }
@@ -181,6 +181,7 @@ int gemtag_transceive(struct gemtag_handle *gh,unsigned char cmd,
 }
 
 struct gemtag_handle *gemtag_open(void) {
+
 	struct usb_device *gemtag;
 	unsigned int i;
 	struct gemtag_handle *gh;
@@ -252,13 +253,28 @@ int gemtag_transform_mifare_key(struct gemtag_handle *gh,
 	return 0;
 }
 
-int gemtag_auth_key(struct gemtag_handle *gh,unsigned char authmode,
-                    int sector,unsigned char *key6) {
+int gemtag_auth_e2(struct gemtag_handle *gh,unsigned char authmode,
+                   int sector,unsigned char *key6) {
 
 	unsigned char buf[32];
 	unsigned int len,ret;
 
-	/* to be continued */
+	/* memory layout (sector/block) ? */
+
+	buf[0]=authmode;
+	buf[1]=0;
+	memcpy(buf+2,key6,6);
+	ret=gemtag_transceive(gh,GEMTAG_CMD_PCD_LOAD_KEY_E2,buf,8,buf,&len);
+	if(ret) return -LOAD_E2_FAILED;
+
+	buf[0]=authmode;
+	memcpy(buf+1,gh->serial,4);
+	buf[5]=0;
+	buf[6]=sector;
+	ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_AUTH_E2,buf,7,buf,&len);
+	if(ret) return -AUTH_E2_FAILED;
+
+	return 0;
 
 }
 
@@ -302,8 +318,9 @@ int gemtag_write16(struct gemtag_handle *gh,int sector,unsigned char *data) {
 	buf[0]=sector;
 	memcpy(buf+1,data,16);
 	ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_WRITE,buf,17,buf,&len);
+	if(ret) return -WRITE_FAILED;
 
-	return ret;
+	return 0;
 }
 
 int gemtag_select_picc(struct gemtag_handle *gh) {
@@ -342,14 +359,6 @@ int main(int argc, char **argv) {
 	gh->caps|=GEMTAG_CAP_CRC;
 	//gh->caps|=GEMTAG_CAP_VERB_TRANSMIT;
 
-	/*
-	printf("Device:\n");
-	gemtag_transceive(gh,GEMTAG_CMD_GET_FW_VERSION,
-			  NULL,0,buf,&buflen);
-	asciidump(buf,buflen);
-	printf("\n");
-	*/
-
 	if(gemtag_select_picc(gh)) {
 		printf("no card found!\n");
 		return -NO_PICC;
@@ -360,7 +369,7 @@ int main(int argc, char **argv) {
 	       gh->serial[3],gh->serial[2],gh->serial[1],gh->serial[0]);
 	i=0;
 	while(!gemtag_auth_mifare_key(gh,key6,i)) {
-		gemtag_read16(gh,i,buf);
+		ret=gemtag_read16(gh,i,buf);
 		printf("%02x: ",i);
 		hexdump(buf,16);
 		printf(" | ");
@@ -370,23 +379,6 @@ int main(int argc, char **argv) {
 	}
 	printf("\n");
 
-	/* try to write some data */
-	printf("write some data to the sector 04:\n");
-	for(i=0;i<16;i++) buf[i]=i;
-	i=4;
-	ret=gemtag_auth_mifare_key(gh,key6,i);
-	printf("return = %d\n",ret);
-	if(ret) printf("auth failed!\n");
-	ret=gemtag_write16(gh,i,buf);
-	if(ret) printf("write failed!\n");
-	printf("return = %d\n",ret);
-	ret=gemtag_read16(gh,i,buf);
-	if(ret) printf("read failed!\n");
-	printf("return = %d\n",ret);
-	printf("%02x: ",i);
-	hexdump(buf,16);
-	printf("\n");
-
 	gemtag_close(gh);
 
 	return 0;
diff --git a/gemtag/gemtag.h b/gemtag/gemtag.h
index dfdfa64..e5c24bf 100644
--- a/gemtag/gemtag.h
+++ b/gemtag/gemtag.h
@@ -1,5 +1,6 @@
 /*
- * (C) 2006 by Frank Zirkelbach <hackbard@hackdaworld.org>
+ * (C) 2006 by Harald Welte <laforge@gnumonks.org>
+ *             Frank Zirkelbach <hackbard@hackdaworld.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 
@@ -47,6 +48,8 @@ struct gemtag_cmd_hdr {
 #define WRITE_FAILED			0x07
 #define NO_PICC				0x08
 #define PICC_SELECT_ERROR		0x09
+#define LOAD_E2_FAILED			0x0a
+#define AUTH_E2_FAILED			0x0b
 
 /* gemtag commands */
 
@@ -122,6 +125,7 @@ struct gemtag_cmd_hdr {
 
 
 /* function prototypes */
+
 int asciidump(unsigned char *data,int len);
 int hexdump(unsigned char *data,int len);
 struct usb_device *find_device(unsigned short vendor,unsigned short device);
@@ -133,6 +137,8 @@ struct gemtag_handle *gemtag_open(void);
 int gemtag_close(struct gemtag_handle *gh);
 int gemtag_transform_mifare_key(struct gemtag_handle *gh,
                                 unsigned char *key6,unsigned char *key12);
+int gemtag_auth_e2(struct gemtag_handle *gh,unsigned char authmode,
+                   int sector,unsigned char *key6);
 int gemtag_auth_mifare_key(struct gemtag_handle *gh,
                            unsigned char *key6,int sector);
 int gemtag_read16(struct gemtag_handle *gh,int sector,unsigned char *data);
-- 
2.39.5