--- krb5-1.2.1-fresh/lib/crypto/des/sc_cbc.c	Wed Dec 31 19:00:00 1969
+++ krb5-1.2.1/lib/crypto/des/sc_cbc.c	Mon Jul 17 16:14:43 2000
@@ -0,0 +1,281 @@
+#ifdef KRBSC
+#include <krb5.h>
+#include <scrw.h>
+#include <assert.h>
+#include <string.h>
+#include "des_int.h"
+#include "krbsc.h"
+
+#define SMARTCARD_CBC_LEN 0xf8
+
+/* global */
+#define CLASS_0 0
+#define CLASS_F0 0xf0
+int cla = CLASS_0;
+#define SERV_PORT                9877                   /* UDP port */
+#define CLA_KRB5 0x03
+#define INS_DECRYPT 0x10
+#define INS_GET_KEY_NUM 0x20
+#define INS_SET_KEY_NUM 0x30
+
+/* function forward declarations */
+static int sc_encrypt_locl (const mit_des_cblock FAR *in, 
+			    mit_des_cblock FAR *out, 
+			    long length, 
+			    mit_des_cblock ivec, 
+			    int encrypt);
+
+int
+sc_encrypt (in, out, length, ivec, encrypt)
+	const mit_des_cblock FAR *in;
+	mit_des_cblock FAR *out;
+	long length;
+	mit_des_cblock ivec;
+	int encrypt;
+{
+  /* check arguments */
+  if (encrypt) {
+    fprintf(stderr, "encrypt=%d.  Sorry, I cannot encrypt with a smartcard yet ...\n", encrypt);
+    return -1;
+  }
+  
+  if (length <= 0) {
+    fprintf(stderr, "sc_decrypt: invalid length %d.\n", length);
+    return -1;
+  }
+
+  if (length % 8 != 0) {
+    fprintf(stderr, "sc_decrypt: invalid length %d.\n", length);
+    return -1;
+  }
+  
+  return sc_encrypt_locl (in, out, length, ivec, encrypt); 
+}
+
+/* decrypt "in" and put it to "out" 
+   using sc7816 library */
+
+static int sc_encrypt_locl (in, out, length, ivec, encrypt)
+	const mit_des_cblock FAR *in;
+	mit_des_cblock FAR *out;
+	long length;
+	mit_des_cblock ivec;
+	int encrypt;
+{
+  int port = KRB5_SC_PORTNUM;
+  int len, r1, r2;
+  int tmplength, i, j, fd, rv, key_file_len = 0, key_number = 0;
+  unsigned char buf[256];
+  krb5_octet *tmp_in = (krb5_octet *)in;
+  krb5_octet *tmp_out = (krb5_octet *)malloc(length);
+  krb5_octet *tmp_begin = tmp_out;
+  int err;
+  
+  appletID = "CITI-krb5";
+
+#ifdef SCDEBUG 
+  printf ("sc_encrypt_locl()! :) \n");
+#endif /* SCDEBUG */
+
+    /* open smartcard */
+  /*fd = scopen(1, SCODSR, NULL);*/
+
+  fd = scopen(port, 0, NULL);
+
+    if (fd < 0) {
+      fprintf(stderr, "can't open port %d\n", port);
+      return -1;
+    }
+    
+    /* reset */
+    i = scxreset(fd, SCRFORCE, buf, &err);
+    /*printf("scxreset returns i=%d, err=%d\n", i, err); */
+    if (!i) {
+      printf("Card reset does not return ATR.\n");
+      return -1; 
+    } else  {
+#ifdef SCDEBUG
+      printf("atr: ");
+      for (j=0; j<i; j++) printf("%x ", buf[j]); 
+      printf("\n");
+#endif SCDEBUG
+    }
+
+    /* set cwt twice */
+  /* do I need it?? */
+  scparam[port].cwt *= 2;
+  /*printf("cwt=%d\n", scparam[port].cwt);*/
+    
+  /* now set speed! */
+  /*
+     if (rv = scsetbaud(fd)){
+     printf("scsetbaud(%d) returned %d\n", fd, rv);
+     return -1; 
+     }
+     */
+
+  /* first of all, figure out what the class byte for this card is */
+  rv = scwrite(fd,  0x00, 0x2a, 0x00, 0x00, 0x00, NULL, &r1, &r2);
+  if (r1 == 0x63) cla = CLASS_0; /* 00 card */
+  else if (r1 == 0x6d) cla = CLASS_F0; /* f0 card */
+      else {
+#ifdef SCDEBUG
+	printf("trying to figure out if this is 00 or f0 card: ");
+#endif SCDEBUG
+	print_r1r2 (r1, r2); 
+	return -1;
+      }
+
+  /* select applet */
+  rv = scwrite (fd, cla, 0xa4, 0x04, 0x00, strlen (appletID),
+		appletID, &r1, &r2);
+  if (r1 != 0x90 && r1 != 0x61) {
+    /* error */
+    printf("selecting applet %s failed: ", appletID);
+    print_r1r2(r1, r2);
+     /* return -1; */
+  }
+  
+  r1 = r2 = 0; 
+  /* If EECS 598 mode, skip get_key_number APDU. */
+  if (!KRB5_EECS_598) {
+    /* get the key number */
+    
+    /* send out get_key_number APDU
+       
+       get key number:	
+       ic 03 20 00 00 0
+    */
+    
+    rv = scwrite (fd, CLA_KRB5, INS_GET_KEY_NUM, 0x00, 0x00, 0, 0, &r1, &r2);
+    if (rv == -1 || r1 != 0x90 && r1 != 0x61) {
+      /* error */
+      printf("sending get_key_number APDU: ");
+      print_r1r2(r1, r2);
+      return -1; 
+    }
+
+    key_file_len = r2;
+
+    rv = scread (fd, cla, 0xc0, 0, 0, key_file_len, buf, &r1, &r2);
+    if (rv == -1 || r1 != 0x90 && r1 != 0x61) {
+      /* error */
+      printf("get_response APDU: ");
+      print_r1r2(r1, r2);
+      return -1; 
+    }
+
+    /*printf ("key_file (%d)\n", key_file_len);
+    for (i = 0 ; i < key_file_len ; i ++)
+      printf ("%c", buf[i]);
+      printf ("\n");*/
+
+    key_number = parse_keyfile (global_client_name,
+				strlen (global_client_name),
+				buf, key_file_len);
+
+#ifdef SCDEBUG 
+    printf ("parse_keyfile (%s) -> %d\n", global_client_name, key_number);
+#endif /* SCDEBUG */
+
+    /* set key number */
+    buf[0] = (unsigned char)(key_number & 0xff); 
+    rv = scwrite (fd, CLA_KRB5, INS_SET_KEY_NUM, 0x00, 0x00, 1, buf, &r1, &r2);
+    if (rv == -1 || r1 != 0x90 && r1 != 0x61) {
+      /* error */
+      printf("sending set_key_number APDU: ");
+      print_r1r2(r1, r2);
+      return -1; 
+    }
+  }
+
+#ifdef SCDEBUG
+    printf("TKT length = %d\n", length); 
+#endif SCDEBUG
+    /* send decrupt APDU */
+    for (i=0; i< (length-1)/SMARTCARD_CBC_LEN + 1; i++) {
+	tmplength = (length - SMARTCARD_CBC_LEN * i > SMARTCARD_CBC_LEN ?
+		     SMARTCARD_CBC_LEN :
+		     length - SMARTCARD_CBC_LEN * i);
+#ifdef SCDEBUG
+	printf("i=%d, tmplength = %d\n", i, tmplength);
+#endif
+	len = scwrite(fd, CLA_KRB5, INS_DECRYPT, 0x00, 0x00, tmplength, tmp_in, &r1, &r2);
+      if (len != tmplength || r1 != 0x61 || r2 != tmplength) {
+#ifdef SCDEBUG
+	printf("scwrite returns len %d %02x %02x\n", len, r1, r2);
+#endif
+	print_r1r2 (r1, r2); 
+	return -1;
+      }
+     
+      len = scread(fd,  cla, 0xc0, 0x00, 0x00, tmplength, tmp_out, &r1, &r2);
+
+      if (len != tmplength || r1 != 0x90 || r2 != 0x00) {
+#ifdef SCDEBUG
+	printf("getresponse returns len %d %02x %02x\n", len, r1, r2);
+#endif
+	return -1;
+      }
+      tmp_in += tmplength;
+      tmp_out += tmplength;
+    }
+    scclose(fd);
+
+    for (i=0; i*8<length; i++) {
+      for (j=0; j<8; j++) {
+	out[i][j] = tmp_begin[8*i+j];
+      }
+    }
+
+    /* take care of IV */
+    for (i=0; i<8; i++){
+      out[0][i] = out[0][i] ^ ivec[i];
+    }
+
+    /* quick bug fix of Cyberflex Access */
+  /*printf ("FIX: ");
+    for (i=0; i<8; i++){
+      if (cla == CLASS_0) {
+#ifdef SCDEBUG
+	printf ("%02x ", cyberflex_access_fix_class_0[i]); 
+#endif 	
+
+	out[0][i] = out[0][i] ^ cyberflex_access_fix_class_0[i];
+      }
+      else {
+#ifdef SCDEBUG
+	printf ("%02x ", cyberflex_access_fix_class_0[i]); 
+#endif 	
+	out[0][i] = out[0][i] ^ cyberflex_access_fix_class_0[i];
+      }
+    }
+  printf ("\n");*/
+
+    free(tmp_begin);
+      
+    return 0;
+}
+
+open_file(fd, f0, f1)
+int fd, f0, f1;
+{
+    char buf[2];
+    int len, r1, r2;
+
+    buf[0] = f0;
+    buf[1] = f1;
+
+    len = scwrite(fd, 0x00, 0xa4, 0, 0x0c, 2, buf, &r1, &r2);
+
+    if (len != 2 || r1 != 144 || r2 != 0) {
+#ifdef SCDEBUG
+	printf("scwrite returns len %d %02x %02x\n", len, r1, r2);
+#endif
+      return -1;
+    }
+    return 0;
+}
+
+
+#endif /* KRBSC */
