Annotation of src/usr.bin/sectok/cyberflex.c, Revision 1.3
1.2 rees 1: /* $Id: cyberflex.c,v 1.1 2001/06/27 19:41:45 rees Exp $ */
1.1 rees 2:
3: /*
4: copyright 1999, 2000
5: the regents of the university of michigan
6: all rights reserved
7:
8: permission is granted to use, copy, create derivative works
9: and redistribute this software and such derivative works
10: for any purpose, so long as the name of the university of
11: michigan is not used in any advertising or publicity
12: pertaining to the use or distribution of this software
13: without specific, written prior authorization. if the
14: above copyright notice or any other identification of the
15: university of michigan is included in any copy of any
16: portion of this software, then the disclaimer below must
17: also be included.
18:
19: this software is provided as is, without representation
20: from the university of michigan as to its fitness for any
21: purpose, and without warranty by the university of
22: michigan of any kind, either express or implied, including
23: without limitation the implied warranties of
24: merchantability and fitness for a particular purpose. the
25: regents of the university of michigan shall not be liable
26: for any damages, including special, indirect, incidental, or
27: consequential damages, with respect to any claim arising
28: out of or in connection with the use of the software, even
29: if it has been or is hereafter advised of the possibility of
30: such damages.
31: */
32:
33: #include <unistd.h>
34: #include <stdlib.h>
35: #include <stdio.h>
36: #include <signal.h>
37: #include <string.h>
38: #include <fcntl.h>
39: #ifdef __linux
40: #include <openssl/des.h>
41: #else /* __linux */
42: #include <des.h>
43: #endif
44: #include <sectok.h>
1.3 ! rees 45: #include <sc7816.h>
1.1 rees 46:
47: #include "sc.h"
48:
49: #ifdef __sun
50: #define des_set_key(key, schedule) des_key_sched(key, schedule)
51: #endif
52:
53: #define MAX_KEY_FILE_SIZE 1024
54: #define NUM_RSA_KEY_ELEMENTS 5
55: #define RSA_BIT_LEN 1024
56: #define KEY_FILE_HEADER_SIZE 8
57:
58: static unsigned char key_fid[] = {0x00, 0x11};
59: static unsigned char DFLTATR[] = {0x81, 0x10, 0x06, 0x01};
60: static unsigned char AUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
61:
62: /* default signed applet key of Cyberflex Access */
63: static des_cblock app_key = {0x6A, 0x21, 0x36, 0xF5, 0xD8, 0x0C, 0x47, 0x83};
64:
65: char *apptype[] = {
66: "?",
67: "applet",
68: "app",
69: "app/applet",
70: };
71:
72: char *appstat[] = {
73: "?",
74: "created",
75: "installed",
76: "registered",
77: };
78:
79: char *filestruct[] = {
80: "binary",
81: "fixed rec",
82: "variable rec",
83: "cyclic",
84: "program",
85: };
86:
87: int jdefault(int ac, char *av[])
88: {
89: unsigned char buf[8];
90: int i, p1 = 4, r1, r2;
91:
92: optind = optreset = 1;
93:
94: while ((i = getopt(ac, av, "d")) != -1) {
95: switch (i) {
96: case 'd':
97: p1 = 5;
98: break;
99: }
100: }
101:
102: if (fd < 0)
103: reset(0, NULL);
104:
105: scwrite(fd, cla, 0x08, p1, 0, 0, buf, &r1, &r2);
106: if (r1 != 0x90) {
107: /* error */
108: print_r1r2(r1, r2);
109: return -1;
110: }
111: return 0;
112: }
113:
114: int jatr(int ac, char *av[])
115: {
116: unsigned char buf[64];
117: int n = 0, r1, r2;
118:
119: if (fd < 0)
120: reset(0, NULL);
121:
122: buf[n++] = 0x90;
123: buf[n++] = 0x94; /* TA1 */
124: buf[n++] = 0x40; /* TD1 */
125: buf[n++] = 0x28; /* TC2 (WWT=4sec) */
126: if (ac > optind) {
127: /* set historical bytes from command line */
128: n += parse_input(av[1], &buf[n], 15);
129: } else {
130: /* no historical bytes given, use default */
131: memmove(&buf[n], DFLTATR, sizeof DFLTATR);
132: n += sizeof DFLTATR;
133: }
134: buf[0] |= ((n - 2) & 0xf);
135: scwrite(fd, cla, 0xfa, 0, 0, n, buf, &r1, &r2);
136: if (r1 != 0x90) {
137: /* error */
138: print_r1r2(r1, r2);
139: return -1;
140: }
141: return 0;
142: }
143:
144: int jdata(int ac, char *av[])
145: {
146: unsigned char buf[32];
147: int i, r1, r2;
148:
149: if (fd < 0)
150: reset(0, NULL);
151:
152: scread(fd, cla, 0xca, 0, 1, 0x16, buf, &r1, &r2);
153: if (r1 == 0x90) {
154: printf("serno ");
155: for (i = 0; i < 6; i++)
156: printf("%02x ", buf[i]);
157: printf("batch %02x sver %d.%02d ", buf[6], buf[7], buf[8]);
158: if (buf[9] == 0x0c)
159: printf("augmented ");
160: else if (buf[9] == 0x0b)
161: ;
162: else
163: printf("unknown ");
164: printf("crypto %9.9s class %02x\n", &buf[10], buf[19]);
165: } else {
166: /* error */
167: print_r1r2(r1, r2);
168: }
169: return 0;
170: }
171:
172: #define JDIRSIZE 40
173:
174: int ls(int ac, char *av[])
175: {
176: int p2, f0, f1, r1, r2;
177: char ftype[32], fname[6];
178: unsigned char buf[JDIRSIZE];
179:
180: if (fd < 0)
181: reset(0, NULL);
182:
183: for (p2 = 0; ; p2++) {
184: if (scread(fd, cla, 0xa8, 0, p2, JDIRSIZE, buf, &r1, &r2) < 0)
185: break;
186: if (r1 != 0x90)
187: break;
188: f0 = buf[4];
189: f1 = buf[5];
190: if (f0 == 0xff || f0 + f1 == 0)
191: continue;
192: sectok_fmt_fid(fname, f0, f1);
193: if (buf[6] == 1)
194: /* root */
195: sprintf(ftype, "root");
196: else if (buf[6] == 2) {
197: /* DF */
198: if (buf[12] == 27)
199: sprintf(ftype, "%s %s", appstat[buf[10]], apptype[buf[9]]);
200: else
201: sprintf(ftype, "directory");
202: } else if (buf[6] == 4)
203: /* EF */
204: sprintf(ftype, "%s", filestruct[buf[13]]);
205: printf("%4s %5d %s\n", fname, (buf[2] << 8) | buf[3], ftype);
206: }
207: return 0;
208: }
209:
1.3 ! rees 210: int jcreate(int ac, char *av[])
! 211: {
! 212: unsigned char fid[2];
! 213: int sw, fsize;
! 214:
! 215: if (ac != 3) {
! 216: printf("usage: create fid size\n");
! 217: return -1;
! 218: }
! 219:
! 220: sectok_parse_fname(av[1], fid);
! 221: sscanf(av[2], "%d", &fsize);
! 222:
! 223: if (fd < 0)
! 224: reset(0, NULL);
! 225:
! 226: if (cyberflex_create_file(fd, cla, fid, fsize, 3, &sw) < 0) {
! 227: printf("create_file: %s\n", sectok_get_sw(sw));
! 228: return -1;
! 229: }
! 230:
! 231: return 0;
! 232: }
! 233:
! 234: int jdelete(int ac, char *av[])
! 235: {
! 236: unsigned char fid[2];
! 237: int sw;
! 238:
! 239: if (ac != 2) {
! 240: printf("usage: delete fid\n");
! 241: return -1;
! 242: }
! 243:
! 244: sectok_parse_fname(av[1], fid);
! 245:
! 246: if (fd < 0)
! 247: reset(0, NULL);
! 248:
! 249: if (cyberflex_delete_file(fd, cla, fid, &sw) < 0) {
! 250: printf("delete_file: %s\n", sectok_get_sw(sw));
! 251: return -1;
! 252: }
! 253:
! 254: return 0;
! 255: }
! 256:
1.1 rees 257: int jaut(int ac, char *av[])
258: {
259: if (fd < 0)
260: reset(0, NULL);
261:
262: cla = cyberflex_inq_class(fd);
263: printf("Class %02x\n", cla);
264: return cyberflex_verify_AUT0(fd, cla, AUT0, sizeof AUT0);
265: }
266:
267: #define MAX_BUF_SIZE 256
268: #define MAX_APP_SIZE 4096
269: #define MAX_APDU_SIZE 0xfa
270: #define BLOCK_SIZE 8
271: #define MAXTOKENS 16
272:
273: unsigned char *app_name;
274: unsigned char progID[2], contID[2], aid[MAX_BUF_SIZE];
275: int cont_size, inst_size;
276: int aid_len;
277:
278: int analyze_load_options(int ac, char *av[])
279: {
280: int i, rv;
281:
282: progID[0] = 0x77;
283: progID[1] = 0x77;
284: contID[0] = 0x77;
285: contID[1] = 0x78;
286: cont_size = 1152;
287: inst_size = 1024;
288: aid_len = 5;
289:
290: for (i = 0 ; i < 16 ; i ++)
291: aid[i] = 0x77;
292:
293: /* applet file name */
294: app_name = av[ac - 1];
295:
296: optind = optreset = 1;
297:
298: /* switch on options */
299: while (1) {
300: rv = getopt (ac, av, "p:c:s:i:a:");
301: if (rv == -1) break;
302: /*printf ("rv=%c, optarg=%s\n", rv, optarg);*/
303: switch (rv) {
304: case 'p':
305: parse_input(optarg, progID, 2);
306: break;
307: case 'c':
308: parse_input(optarg, contID, 2);
309: break;
310: case 's':
311: sscanf(optarg, "%d", &cont_size);
312: break;
313: case 'i':
314: sscanf(optarg, "%d", &inst_size);
315: break;
316: case 'a':
317: aid_len = parse_input(optarg, aid, sizeof aid);
318: /*printf ("aid_len = %d\n", aid_len);*/
319: break;
320: default:
321: printf ("unknown option. command aborted.\n");
322: return -1;
323: }
324: }
325:
326: return 0;
327: }
328:
329: int jload(int ac, char *av[])
330: {
331: char progname[5], contname[5];
332: unsigned char app_data[MAX_APP_SIZE],
333: data[MAX_BUF_SIZE];
1.3 ! rees 334: int i, j, fd_app, size, rv, sw, r1, r2;
1.1 rees 335: des_cblock tmp;
336: des_key_schedule schedule;
337:
338: if (analyze_load_options(ac, av) < 0)
339: return -1;
340:
341: if (fd < 0)
342: reset(0, NULL);
343:
344: sectok_fmt_fid(progname, progID[0], progID[1]);
345: sectok_fmt_fid(contname, contID[0], contID[1]);
346:
347: printf ("applet file \"%s\"\n", app_name);
348: printf ("program ID %s\n", progname);
349: printf ("container ID %s\n", contname);
350: printf ("instance container size %d\n", cont_size);
351: printf ("instance data size %d\n", inst_size);
352: printf ("AID ");
353: for (i = 0 ; i < aid_len ; i ++ )
354: printf ("%02x", (unsigned char)aid[i]);
355: printf ("\n");
356:
357: /* open the input file */
358: fd_app = open (app_name, O_RDONLY, NULL);
359: if (fd_app == -1) {
360: fprintf (stderr, "cannot open file \"%s\"\n", app_name);
361: return -1;
362: }
363:
364: /* read the input file */
365: size = read (fd_app, app_data, MAX_APP_SIZE);
366: if (size == 0) {
367: fprintf (stderr, "file %s size 0??\n", app_name);
368: return -1;
369: }
370: if (size == -1) {
371: fprintf (stderr, "error reading file %s\n", app_name);
372: return -1;
373: }
374:
375: /*printf ("file size %d\n", size);*/
376:
377: /* size must be able to be divided by BLOCK_SIZE */
378: if (size % BLOCK_SIZE != 0) {
379: fprintf (stderr, "file (%s) size cannot be divided by BLOCK_SIZE.\n",
380: app_name);
381: return -1;
382: }
383:
384: /* compute the signature of the applet */
385: /* initialize the result buffer */
386: for (j = 0; j < BLOCK_SIZE; j++ ) {
387: tmp[j] = 0;
388: }
389:
390: /* chain. DES encrypt one block, XOR the cyphertext with the next block,
391: ... continues until the end of the buffer */
392:
393: des_set_key (&app_key, schedule);
394:
395: for (i = 0; i < size/BLOCK_SIZE; i++) {
396: for (j = 0; j < BLOCK_SIZE; j++ ){
397: tmp[j] = tmp[j] ^ app_data[i*BLOCK_SIZE + j];
398: }
399: des_ecb_encrypt (&tmp, &tmp, schedule, DES_ENCRYPT);
400: }
401:
402: /* print out the signature */
403: printf ("signature ");
404: for (j = 0; j < BLOCK_SIZE; j++ ) {
405: printf ("%02x", tmp[j]);
406: }
407: printf ("\n");
408:
409: /* select the default loader */
410: rv = scwrite(fd, cla, 0xa4, 0x04, 0, 0, NULL, &r1, &r2);
411: if (r1 != 0x90 && r1 != 0x61) {
412: /* error */
1.2 rees 413: printf("can't select default loader: %s\n", get_r1r2s(r1, r2));
1.1 rees 414: return -1;
415: }
416:
417: /* select 3f.00 (root) */
1.3 ! rees 418: if (sectok_selectfile(fd, cla, root_fid, &sw) < 0)
1.2 rees 419: return -1;
1.1 rees 420:
421: /* create program file */
1.3 ! rees 422: if (cyberflex_create_file(fd, cla, progID, size, 3, &sw) < 0) {
1.1 rees 423: /* error */
1.3 ! rees 424: printf("can't create %s: %s\n", progname, sectok_get_sw(sw));
1.1 rees 425: return -1;
426: }
427:
428: /* update binary */
429: for (i = 0; i < size; i += MAX_APDU_SIZE) {
430: int send_size;
431:
432: /* compute the size to be sent */
433: if (size - i > MAX_APDU_SIZE) send_size = MAX_APDU_SIZE;
434: else send_size = size - i;
435:
436: rv = scwrite(fd, cla, 0xd6,
437: i / 256, /* offset, upper byte */
438: i % 256, /* offset, lower byte */
439: send_size,
440: app_data + i, /* program file */
441: &r1, &r2);
442:
443: if (r1 != 0x90 && r1 != 0x61) {
444: /* error */
445: printf("updating binary %s: %s\n", progname, get_r1r2s(r1, r2));
446: return -1;
447: }
448: }
449:
450: /* manage program .. validate */
451: rv = scwrite(fd, cla, 0x0a, 01, 0, 0x08,
452: tmp, /* signature */
453: &r1, &r2);
454:
455: if (r1 != 0x90 && r1 != 0x61) {
456: /* error */
457: printf("validating applet in %s: %s\n", progname, get_r1r2s(r1, r2));
458: return -1;
459: }
460:
461: /* select the default loader */
462: rv = scwrite(fd, cla, 0xa4, 0x04, 0, 0, NULL, &r1, &r2);
463: if (r1 != 0x90 && r1 != 0x61) {
464: /* error */
465: printf("selecting default loader: %s\n", get_r1r2s(r1, r2));
466: return -1;
467: }
468:
469: /* execute method -- call the install() method in the cardlet.
470: cardlet type 01 (applet, not application)
471: program ID (7777)
472: instance container size (0800 (1152))
473: instance container ID (7778)
474: instance data size (0400 (1024))
475: AID length (0005 (5 byte))
476: AID (7777777777) */
477:
478: data[0] = 0x01; /* cardlet type = 1 (applet, not application) */
479: data[1] = progID[0]; /* FID, upper */
480: data[2] = progID[1]; /* FID, lower */
481: data[3] = cont_size / 256; /* instance container size 0x0800 (1152) byte, upper */
482: data[4] = cont_size % 256; /* instance container size 0x0800 (1152) byte, lower */
483: data[5] = contID[0]; /* container ID (7778), upper */
484: data[6] = contID[1]; /* container ID (7778), lower */
485: data[7] = inst_size / 256; /* instance size 0x0400 (1024) byte, upper */
486: data[8] = inst_size % 256; /* instance size 0x0400 (1024) byte, lower */
487: data[9] = 0x00; /* AID length 0x0005, upper */
488: data[10] = aid_len; /* AID length 0x0005, lower */
489: for (i = 0; i < aid_len; i++) data[i + 11] = (unsigned int)aid[i];
490: /* AID (7777777777) */
491:
492: rv = scwrite(fd, cla, 0x0c, 0x13, 0, 11 + aid_len, data, &r1, &r2);
493: if (r1 != 0x90 && r1 != 0x61) {
494: /* error */
495: printf("executing install() method in applet %s: %s\n", progname, get_r1r2s(r1, r2));
496: return -1;
497: }
498:
499: /* That's it! :) */
500: return 0;
501: }
502:
503: int junload(int ac, char *av[])
504: {
505: char progname[5], contname[5];
1.3 ! rees 506: int sw, r1, r2, rv;
1.1 rees 507:
508: if (analyze_load_options(ac, av) < 0)
509: return -1;
510:
511: if (fd < 0)
512: reset(0, NULL);
513:
514: sectok_fmt_fid(progname, progID[0], progID[1]);
515: sectok_fmt_fid(contname, contID[0], contID[1]);
516:
517: printf ("program ID %s\n", progname);
518: printf ("container ID %s\n", contname);
519: /*printf ("AID ");
520: for (i = 0 ; i < aid_len ; i ++ ) {
521: printf ("%02x", (unsigned char)aid[i]);
522: }
523: printf ("\n");*/
524:
525: /*printf ("unload applet\n");*/
526:
527: /* select 3f.00 (root) */
1.3 ! rees 528: if (sectok_selectfile(fd, cla, root_fid, &sw) < 0) {
! 529: printf("can't select root: %s\n", sectok_get_sw(sw));
1.2 rees 530: return -1;
1.3 ! rees 531: }
1.1 rees 532:
533: /* select program file */
1.3 ! rees 534: if (sectok_selectfile(fd, cla, progID, &sw) >= 0) {
1.1 rees 535:
1.2 rees 536: /* manage program -- reset */
537: rv = scwrite(fd, cla, 0x0a, 02, 0, 0x0, NULL, &r1, &r2);
538: if (rv < 0 || (r1 != 0x90 && r1 != 0x61)) {
539: /* error */
540: printf("resetting applet: %s\n", get_r1r2s(r1, r2));
541: }
1.1 rees 542:
1.2 rees 543: /* delete program file */
1.3 ! rees 544: if (cyberflex_delete_file(fd, cla, progID, &sw) < 0)
! 545: printf("delete_file %s: %s\n", progname, sectok_get_sw(sw));
1.2 rees 546: } else
547: printf ("no program file... proceed to delete data container\n");
1.1 rees 548:
549: /* delete data container */
1.3 ! rees 550: if (cyberflex_delete_file(fd, cla, contID, &sw) < 0)
! 551: printf("delete_file %s: %s\n", contname, sectok_get_sw(sw));
1.1 rees 552:
553: return 0;
554: }
555:
556: int jselect(int ac, char *av[])
557: {
558: int i, r1, r2, rv;
559: unsigned char data[MAX_BUF_SIZE];
560:
561: optind = optreset = 1;
562:
563: if (analyze_load_options(ac, av) < 0)
564: return -1;
565:
566: if (fd < 0)
567: reset(0, NULL);
568:
569: printf ("select applet\n");
570: printf ("AID ");
571: for (i = 0 ; i < aid_len ; i ++ )
572: printf ("%02x", (unsigned char)aid[i]);
573: printf ("\n");
574:
575: /* select the cardlet (7777777777) */
576: for (i = 0; i < aid_len; i++) data[i] = (unsigned char)aid[i];
577: /* quick hack in select_applet()
578: even with F0 card, select applet APDU (00 a4 04)
579: only accepts class byte 00 (not f0) */
580:
581: rv = scwrite(fd, cla, 0xa4, 0x04, 0, aid_len, data, &r1, &r2);
582: if (r1 != 0x90 && r1 != 0x61) {
583: /* error */
584: printf ("selecting the cardlet: ");
585: for (i = 0 ; i < aid_len ; i ++ ) {
586: printf ("%02x", (unsigned char)aid[i]);
587: }
588: printf ("\n");
589: print_r1r2 (r1, r2);
590: return -1;
591: }
592:
593: return 0;
594: }
595:
596: int jdeselect(int ac, char *av[])
597: {
1.3 ! rees 598: int sw;
1.1 rees 599:
600: if (fd < 0)
601: reset(0, NULL);
602:
1.3 ! rees 603: sectok_apdu(fd, cla, 0xa4, 0x04, 0, 0, NULL, 0, NULL, &sw);
! 604: if (!sectok_swOK(sw)) {
1.1 rees 605: /* error */
1.3 ! rees 606: printf("selecting default loader: %s\n", sectok_get_sw(sw));
1.1 rees 607: return -1;
608: }
609:
610: return 0;
611: }
612:
613: #define DELIMITER " :\t\n"
614: #define KEY_BLOCK_SIZE 14
615:
616: /* download DES keys into 3f.00/00.11 */
617: int cyberflex_load_key (int fd, unsigned char *buf)
618: {
1.3 ! rees 619: int sw, r1, r2, rv, argc = 0, i, j, tmp;
1.1 rees 620: unsigned char *token;
621: unsigned char data[MAX_BUF_SIZE];
622: unsigned char key[BLOCK_SIZE];
623:
624: #if 0
625: /* select the default loader */
626: rv = scwrite(fd, cla, 0xa4, 0x04, 0, 0x00, NULL, &r1, &r2);
627: if (r1 != 0x90 && r1 != 0x61) {
628: // error
629: printf ("selecting the default loader: ");
630: print_r1r2 (r1, r2);
631: return -1;
632: }
633: #endif
634:
635: printf ("ca_load_key buf=%s\n", buf);
636: token = strtok (buf, DELIMITER);
637: token = strtok (NULL, DELIMITER);
638: if (token == NULL) {
639: printf ("Usage: jk number_of_keys\n");
640: return -1;
641: }
642: argc = atoi (token);
643:
644: if (argc > 2) {
645: printf ("current Cyberflex Access cannot download more than 2 keys to the key file. Sorry. :(\n");
646: return -1;
647: }
648:
649: if (argc < 0) {
650: printf ("you want to down load %d keys??\n", argc);
651: return -1;
652: }
653:
654: /* Now let's do it. :) */
655:
656: /* add the AUT0 */
657: cyberflex_fill_key_block (data, 0, 1, AUT0);
658:
659: /* add the applet sign key */
660: cyberflex_fill_key_block (data+KEY_BLOCK_SIZE, 5, 0, app_key);
661:
662: /* then add user defined keys */
663: for ( i = 0 ; i < argc ; i++ ) {
664: printf ("key %d : ", i);
665: for ( j = 0 ; j < BLOCK_SIZE ; j++ ) {
666: fscanf (cmdf, "%02x", &tmp);
667: key[j] = (unsigned char)tmp;
668: }
669:
670: cyberflex_fill_key_block (data + 28 + i*KEY_BLOCK_SIZE, 6 + i, 0, key);
671: }
672:
673: /* add the suffix */
674: data[28 + argc*KEY_BLOCK_SIZE] = 0;
675: data[28 + argc*KEY_BLOCK_SIZE + 1] = 0;
676:
677: for ( i = 0 ; i < KEY_BLOCK_SIZE * (argc + 2) + 2; i++ )
678: printf ("%02x ", data[i]);
679: printf ("\n");
680:
681: /* select 3f.00 (root) */
1.3 ! rees 682: if (sectok_selectfile(fd, cla, root_fid, &sw) < 0) {
! 683: printf("select root: %s\n", sectok_get_sw(sw));
1.2 rees 684: return -1;
1.3 ! rees 685: }
1.1 rees 686:
687: /* select 00.11 (key file) */
1.3 ! rees 688: if (sectok_selectfile(fd, cla, key_fid, &sw) < 0) {
! 689: printf("select key file: %s\n", sectok_get_sw(sw));
1.2 rees 690: return -1;
1.3 ! rees 691: }
1.1 rees 692:
693: /* all righty, now let's send it to the card! :) */
694: rv = scwrite(fd, cla, 0xd6, 0, 0, KEY_BLOCK_SIZE * (argc + 2) + 2,
695: data, &r1, &r2);
696: if (r1 != 0x90 && r1 != 0x61) {
697: /* error */
1.2 rees 698: printf("writing the key file 00.11: %s\n", get_r1r2s(r1, r2));
1.1 rees 699: return -1;
700: }
701:
702: return 0;
703: }
704:
705: /* download AUT0 key into 3f.00/00.11 */
706: int load_AUT0(int fd, unsigned char *buf)
707: {
1.3 ! rees 708: int sw, r1, r2, rv, i, tmp;
1.1 rees 709: unsigned char data[MAX_BUF_SIZE];
710: unsigned char key[BLOCK_SIZE];
711:
712: printf ("load AUT0\n");
713:
714: printf ("ca_load_AUT0 buf=%s\n", buf);
715:
716: /* Now let's do it. :) */
717:
718: /* get the AUT0 */
719: printf ("input AUT0 : ");
720: for ( i = 0 ; i < BLOCK_SIZE ; i++ ) {
721: fscanf (cmdf, "%02x", &tmp);
722: key[i] = (unsigned char)tmp;
723: }
724: cyberflex_fill_key_block (data, 0, 1, key);
725:
726: #if 0
727: /* add the suffix */
728: data[KEY_BLOCK_SIZE] = 0;
729: data[KEY_BLOCK_SIZE + 1] = 0;
730: #endif
731:
732: for ( i = 0 ; i < KEY_BLOCK_SIZE ; i++ )
733: printf ("%02x ", data[i]);
734: printf ("\n");
735:
736: /* select 3f.00 (root) */
1.3 ! rees 737: if (sectok_selectfile(fd, cla, root_fid, &sw) < 0)
1.2 rees 738: return -1;
1.1 rees 739:
740: /* select 00.11 (key file) */
1.3 ! rees 741: if (sectok_selectfile(fd, cla, key_fid, &sw) < 0)
1.2 rees 742: return -1;
1.1 rees 743:
744: /* all righty, now let's send it to the card! :) */
745: rv = scwrite(fd, cla, 0xd6, 0, 0, KEY_BLOCK_SIZE,
746: data, &r1, &r2);
747: if (r1 != 0x90 && r1 != 0x61) {
748: /* error */
1.2 rees 749: printf("writing the key file 00.11: %s\n", get_r1r2s(r1, r2));
1.1 rees 750: return -1;
751: }
752:
753: return 0;
754: }
755:
756: /* download RSA private key into 3f.00/00.12 */
757: int cyberflex_load_rsa(int fd, unsigned char *buf)
758: {
1.3 ! rees 759: int rv, sw, i, j, tmp;
1.1 rees 760: static unsigned char key_fid[] = {0x00, 0x12};
761: static char *key_names[NUM_RSA_KEY_ELEMENTS]= {"p", "q", "1/p mod q",
762: "d mod (p-1)", "d mod (q-1)"};
763: unsigned char *key_elements[NUM_RSA_KEY_ELEMENTS];
764:
765: printf ("ca_load_rsa_priv buf=%s\n", buf);
766:
767: printf ("input 1024 bit RSA CRT key\n");
768: for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++) {
769: printf ("%s (%d bit == %d byte) : ", key_names[i],
770: RSA_BIT_LEN/2, RSA_BIT_LEN/2/8);
771: key_elements[i] = (unsigned char *) malloc(RSA_BIT_LEN/8);
772: for ( j = 0 ; j < RSA_BIT_LEN/8/2 ; j++ ) {
773: fscanf (cmdf, "%02x", &tmp);
774: key_elements[i][j] = (unsigned char)tmp;
775: }
776: }
777:
778: #ifdef DEBUG
779: printf ("print RSA CRT key\n");
780: for (i = 0 ; i < NUM_RSA_KEY_ELEMENTS ; i ++ ) {
781: printf ("%s : ", key_names[i]);
782: for ( j = 0 ; j < RSA_BIT_LEN/8/2 ; j++ ) {
783: printf ("%02x ", key_elements[i][j]);
784: }
785: }
786: #endif
787:
1.2 rees 788: rv = cyberflex_load_rsa_priv(fd, cla, key_fid, NUM_RSA_KEY_ELEMENTS, RSA_BIT_LEN,
1.3 ! rees 789: key_elements, &sw);
1.2 rees 790:
791: if (rv < 0)
1.3 ! rees 792: printf("load_rsa_priv: %s\n", sectok_get_sw(sw));
1.1 rees 793:
794: for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
795: free(key_elements[i]);
796: return rv;
797: }