int main(void) { unsigned char in[BUFSIZE], encrypted[BUFSIZE], decrypted[BUFSIZE]; unsigned char *e = encrypted; int len; DES_cblock key1, key2, key3; DES_cblock seed = {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}; DES_key_schedule ks1, ks2, ks3; DES_cblock ivsetup = {0xE1, 0xE2, 0xE3, 0xD4, 0xD5, 0xC6, 0xC7, 0xA8}; DES_cblock ivec; memset(in, 0, sizeof(in)); memset(encrypted, 0, sizeof(encrypted)); memset(decrypted, 0, sizeof(decrypted)); RAND_seed(seed, sizeof(DES_cblock)); DES_random_key(&key1); DES_random_key(&key2); DES_random_key(&key2); DES_set_key((DES_cblock *)key1, &ks1); DES_set_key((DES_cblock *)key2, &ks2); DES_set_key((DES_cblock *)key3, &ks3); /* plaintext */ strcpy(in, "this is a string encrypted with triple des. it is 64 bytes long."); printf("Plaintext: [%s]\n", in); len = strlen(in); memcpy(ivec, ivsetup, sizeof(ivsetup)); DES_ede3_cbc_encrypt(in, encrypted, len, &ks1, &ks2, &ks3, &ivec, DES_ENCRYPT); printf("Ciphertext:"); while (*e) printf(" [%02x]", *e++); printf("\n"); len = strlen(encrypted); memcpy(ivec, ivsetup, sizeof(ivsetup)); DES_ede3_cbc_encrypt(encrypted, decrypted, len, &ks1, &ks2, &ks3, &ivec, DES_DECRYPT); printf("Decrypted Text: [%s]\n", decrypted); exit(0); }
void EncryptData_model(BYTE * inData, size_t len, const BYTE* key1, const BYTE* key2, const BYTE* key3, t_DES_SPtrans * sp) { assert((len & 0x7) == 0); #ifdef _DEBUG BYTE * oldData = new BYTE[len]; memcpy(oldData, inData, len); #endif DES_key_schedule sKey[3]; DES_set_key((const_DES_cblock*)key1, &sKey[0]); DES_set_key((const_DES_cblock*)key2, &sKey[1]); DES_set_key((const_DES_cblock*)key3, &sKey[2]); for (size_t i = 0; i < len; i += 8) { DES_encrypt3((DWORD*)(inData + i), &sKey[0], &sKey[1], &sKey[2], sp); } #ifdef _DEBUG BYTE* newData = new BYTE[len]; memcpy(newData, inData, len); DecryptData(newData, len, key1, key2, key3); int cmp = memcmp(newData, oldData, len); assert(cmp == 0); CC_SAFE_DELETE_ARRAY(newData); CC_SAFE_DELETE_ARRAY(oldData); #endif }
static int ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) { ossldata *od = c->ptr; DES_cblock xkey1, xkey2, xkey3; memset(&xkey1, 0, sizeof(xkey1)); memset(&xkey2, 0, sizeof(xkey2)); memset(&xkey3, 0, sizeof(xkey3)); memcpy(&xkey1, key, klen > 8 ? 8 : klen); if (klen > 8) memcpy(&xkey2, key + 8, (klen - 8) > 8 ? 8 : (klen - 8)); if (klen > 16) memcpy(&xkey3, key + 16, (klen - 16) > 8 ? 8 : (klen - 16)); DES_set_key(&xkey1, &od->u.des3.k1); DES_set_key(&xkey2, &od->u.des3.k2); DES_set_key(&xkey3, &od->u.des3.k3); memset(&xkey1, 0, sizeof(xkey1)); memset(&xkey2, 0, sizeof(xkey2)); memset(&xkey3, 0, sizeof(xkey3)); if (iv) memcpy(od->iv, iv, 8); else memset(od->iv, 0, 8); return 0; }
static int kcdecrypt(unsigned char *key, unsigned char *iv, unsigned char *data) { unsigned char out[CTLEN]; int pad, n, i; DES_cblock key1, key2, key3; DES_cblock ivec; DES_key_schedule ks1, ks2, ks3; memset(out, 0, sizeof(out)); memcpy(key1, key, 8); memcpy(key2, key + 8, 8); memcpy(key3, key + 16, 8); DES_set_key((C_Block *) key1, &ks1); DES_set_key((C_Block *) key2, &ks2); DES_set_key((C_Block *) key3, &ks3); memcpy(ivec, iv, 8); DES_ede3_cbc_encrypt(data, out, CTLEN, &ks1, &ks2, &ks3, &ivec, DES_DECRYPT); // now check padding pad = out[47]; if(pad > 8) // "Bad padding byte. You probably have a wrong password" return -1; if(pad != 4) /* possible bug here, is this assumption always valid? */ return -1; n = CTLEN - pad; for(i = n; i < CTLEN; i++) if(out[i] != pad) // "Bad padding. You probably have a wrong password" return -1; return 0; }
static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, int enc) { DES_cblock *deskey = (DES_cblock *) key; DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data; DES_set_key(&deskey[0], &dat->ks.ks[0]); DES_set_key(&deskey[1], &dat->ks.ks[1]); DES_set_key(&deskey[0], &dat->ks.ks[2]); return 1; }
enum cryptoerr des3_init(struct keystate *ks, u_int8_t *key, u_int16_t len) { DES_set_odd_parity((void *)key); DES_set_odd_parity((void *)(key + 8)); DES_set_odd_parity((void *)(key + 16)); /* As of the draft Tripe-DES does not check for weak keys */ DES_set_key((void *)key, &ks->ks_des[0]); DES_set_key((void *)(key + 8), &ks->ks_des[1]); DES_set_key((void *)(key + 16), &ks->ks_des[2]); return EOKAY; }
void DecryptData_model(BYTE * inData, size_t len, const BYTE* key1, const BYTE* key2, const BYTE* key3, t_DES_SPtrans * sp) { assert((len & 0x7) == 0); DES_key_schedule sKey[3]; DES_set_key((const_DES_cblock*)key1, &sKey[0]); DES_set_key((const_DES_cblock*)key2, &sKey[1]); DES_set_key((const_DES_cblock*)key3, &sKey[2]); for (size_t i = 0; i < len; i += 8) { DES_decrypt3((DWORD*)(inData + i), &sKey[0], &sKey[1], &sKey[2], sp); } }
/* * This sets the DES key and (if you're using the deszip version) * the direction of the transformation. This uses the Sun * to map the 64-bit key onto the 56 bits that the key schedule * generation routines use: the old way, which just uses the user- * supplied 64 bits as is, and the new way, which resets the parity * bit to be the same as the low-order bit in each character. The * new way generates a greater variety of key schedules, since many * systems set the parity (high) bit of each character to 0, and the * DES ignores the low order bit of each character. */ void set_des_key(DES_cblock *buf) /* key block */ { int i, j; /* counter in a for loop */ int par; /* parity counter */ /* * if the parity is not preserved, flip it */ if (!pflag) { for (i = 0; i < 8; i++) { par = 0; for (j = 1; j < 8; j++) if ((bits[j] & (*buf)[i]) != 0) par++; if ((par & 0x01) == 0x01) (*buf)[i] &= 0x7f; else (*buf)[i] = ((*buf)[i] & 0x7f) | 0x80; } } DES_set_odd_parity(buf); DES_set_key(buf, &schedule); }
static int des_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, int enc) { DES_cblock *deskey = (DES_cblock *)key; EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data; DES_set_key(deskey, &dat->ks.ks); return 1; }
static int ssh_des3_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { struct ssh_des3_ctr_ctx *c; if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { c = malloc(sizeof(*c)); EVP_CIPHER_CTX_set_app_data(ctx, c); } if (key != NULL) { DES_set_key((const_DES_cblock *)key, &c->des3_ctx[0]); DES_set_key((const_DES_cblock *)(key + 8), &c->des3_ctx[1]); DES_set_key((const_DES_cblock *)(key + 16), &c->des3_ctx[2]); } if (iv != NULL) memcpy(c->des3_counter, iv, DES_BLOCK_SIZE); return (1); }
SSH1Encryption::SSH1Encryption(Method method, const QByteArray & key) : m_method(method) { DES_cblock desKey; uint8_t * data = (unsigned char *) key.data(); memset(desKey, 0, sizeof(desKey)); memcpy(desKey, data, sizeof(desKey)); DES_set_key(&desKey, &m_key1); data += 8; memset(desKey, 0, sizeof(desKey)); memcpy(desKey, data, sizeof(desKey)); DES_set_key(&desKey, &m_key2); data += 8; memset(desKey, 0, sizeof(desKey)); memcpy(desKey, data, sizeof(desKey)); DES_set_key(&desKey, &m_key3); memset(m_IV1, 0, sizeof(m_IV1)); memset(m_IV2, 0, sizeof(m_IV2)); memset(m_IV3, 0, sizeof(m_IV3)); }
static void tripledes_init(ops_crypt_t *crypt) { DES_key_schedule *keys; int n; if (crypt->encrypt_key) free(crypt->encrypt_key); keys=crypt->encrypt_key=malloc(3*sizeof(DES_key_schedule)); for(n=0 ; n < 3 ; ++n) DES_set_key((DES_cblock *)(crypt->key+n*8),&keys[n]); }
enum cryptoerr des1_init(struct keystate *ks, u_int8_t *key, u_int16_t len) { /* DES_set_key returns -1 for parity problems, and -2 for weak keys */ DES_set_odd_parity((void *)key); switch (DES_set_key((void *)key, &ks->ks_des[0])) { case -2: return EWEAKKEY; default: return EOKAY; } }
void mschap_des_encrypt(u_int8_t *clear, u_int8_t *key, u_int8_t *cipher) { DES_cblock des_key; DES_key_schedule key_schedule; mschap_des_addparity(key, des_key); DES_set_key(&des_key, &key_schedule); DES_ecb_encrypt((DES_cblock *)clear, (DES_cblock *)cipher, &key_schedule, 1); }
/* XXX - SSH1's weirdo 3DES... */ static void * des3_init(u_char *sesskey, int len) { struct des3_state *state; if ((state = malloc(sizeof(*state))) == NULL) return (NULL); DES_set_key((const_DES_cblock *)sesskey, &state->k1); DES_set_key((const_DES_cblock *)(sesskey + 8), &state->k2); if (len <= 16) DES_set_key((const_DES_cblock *)sesskey, &state->k3); else DES_set_key((const_DES_cblock *)(sesskey + 16), &state->k3); memset(state->iv1, 0, 8); memset(state->iv2, 0, 8); memset(state->iv3, 0, 8); return (state); }
static int krb4_cmp_all(void *binary, int count) { DES_cblock tmp; DES_set_key(&saved_key.key, &saved_key.sched); DES_pcbc_encrypt(saved_salt->tgt, (unsigned char *)&tmp, sizeof(tmp), &saved_key.sched, &saved_key.key, DES_DECRYPT); return (krb4_check_parity(&tmp)); }
static void oracle_init(void) { unsigned char deskey[8]; deskey[0] = 0x01; deskey[1] = 0x23; deskey[2] = 0x45; deskey[3] = 0x67; deskey[4] = 0x89; deskey[5] = 0xab; deskey[6] = 0xcd; deskey[7] = 0xef; DES_set_key((DES_cblock *)deskey, &desschedule1); }
static void oracle_crypt_all(int count) { unsigned char buf[sizeof(cur_salt)]; unsigned int l; l = salt_length + key_length; crypt_key[0] = 0; crypt_key[1] = 0; memcpy((char *)cur_salt + salt_length, cur_key, key_length); DES_ncbc_encrypt((unsigned char *)cur_salt, buf, l, &desschedule1, (DES_cblock *) crypt_key, DES_ENCRYPT); DES_set_key((DES_cblock *)crypt_key, &desschedule2); crypt_key[0] = 0; crypt_key[1] = 0; DES_ncbc_encrypt((unsigned char *)cur_salt, buf, l, &desschedule2, (DES_cblock *) crypt_key, DES_ENCRYPT); }
static int ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) { ossldata *od = c->ptr; DES_cblock xkey; memset(&xkey, 0, sizeof(xkey)); memcpy(&xkey, key, klen > 8 ? 8 : klen); DES_set_key(&xkey, &od->u.des.key_schedule); memset(&xkey, 0, sizeof(xkey)); if (iv) memcpy(od->iv, iv, 8); else memset(od->iv, 0, 8); return 0; }
/* DES: encrypt and decrypt known plaintext, verify result matches original plaintext */ static int FIPS_des_test() { DES_cblock userkey = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xf0, 0x0d }; DES_cblock plaintext = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' }; DES_key_schedule key; DES_cblock ciphertext; DES_cblock buf; ERR_clear_error(); if (DES_set_key(&userkey, &key) < 0) return 0; DES_ecb_encrypt( &plaintext, &ciphertext, &key, 1); DES_ecb_encrypt( &ciphertext, &buf, &key, 0); if (memcmp(buf, plaintext, sizeof(buf))) return 0; return 1; }
static int tripledes_init(pgp_crypt_t *crypt) { DES_key_schedule *keys; int n; if (crypt->encrypt_key) { free(crypt->encrypt_key); } if ((keys = crypt->encrypt_key = calloc(1, 3 * sizeof(DES_key_schedule))) == NULL) { (void) fprintf(stderr, "tripledes_init: alloc failure\n"); return 0; } for (n = 0; n < 3; ++n) { DES_set_key((DES_cblock *)(void *)(crypt->key + n * 8), &keys[n]); } return 1; }
void DES_string_to_key(const char *str, DES_cblock *key) { DES_key_schedule ks; int i,length; register unsigned char j; TINYCLR_SSL_MEMSET(key,0,8); length=TINYCLR_SSL_STRLEN(str); #ifdef OLD_STR_TO_KEY for (i=0; i<length; i++) (*key)[i%8]^=(str[i]<<1); #else /* MIT COMPATIBLE */ for (i=0; i<length; i++) { j=str[i]; if ((i%16) < 8) (*key)[i%8]^=(j<<1); else { /* Reverse the bit order 05/05/92 eay */ j=((j<<4)&0xf0)|((j>>4)&0x0f); j=((j<<2)&0xcc)|((j>>2)&0x33); j=((j<<1)&0xaa)|((j>>1)&0x55); (*key)[7-(i%8)]^=j; } } #endif DES_set_odd_parity(key); #ifdef EXPERIMENTAL_STR_TO_STRONG_KEY if(DES_is_weak_key(key)) (*key)[7] ^= 0xF0; DES_set_key(key,&ks); #else DES_set_key_unchecked(key,&ks); #endif DES_cbc_cksum((const unsigned char*)str,key,length,&ks,key); OPENSSL_cleanse(&ks,sizeof(ks)); DES_set_odd_parity(key); }
int enc(char *sopath,char *filename) { //printf("you are in the enc program\n"); SHA_CTX md; int eight=8; DES_key_schedule schedule1; DES_key_schedule schedule2; DES_key_schedule schedule3; FILE *fp; unsigned char buffer[10],DES_output[8]; char DES_input[8],ch; unsigned char digest[20],file_digest[20]; int count,i,len_of_pass,verify=1,no_of_bytes; unsigned char random_bits1[20],random_bits2[20],DES_key1[8],DES_key2[8],DES_key3[8],IV[8]; char *buf,*buff; if(RAND_bytes(random_bits1,20)==0) { fprintf(stderr,"Error obtaining 20 bytes of random bits from OPENSSL\n"); exit(1); } if(RAND_bytes(random_bits2,20)==0) { fprintf(stderr,"Error obtaining 20 bytes of random bits from OPENSSL\n"); exit(1); } /************************************** COMPUTE SHA1 OF FILE **************************************/ if((fp=fopen(filename,"rb"))==NULL) { fprintf(stderr,"(input file %s does not exist)\n",filename); exit(1); } SHA1_Init(&md); while((count=fread(&buffer,1,10,fp))) { SHA1_Update(&md,buffer,count); } SHA1_Final(file_digest,&md); /* for(i=0;i<20;i++) { printf("%02x",file_digest[i]); }*/ /************************************** ASK FOR PASSWORD FOR DES **************************************/ buf=(char *)malloc(4096*sizeof(char)); buff=(char *)malloc(4096*sizeof(char)); des_read_pw(buf,buff,4096,"Enter passphrase for DES encryption: ",verify); //printf("buff=%s",buf); //printf("buff2=%s\n",buff); len_of_pass=strlen(buf); //printf("len_of_pass=%d\n",len_of_pass); /************************************** GENERATE SHA1 OF THE PASSWORD **************************************/ SHA1_Init(&md); //free(&md); //SHA1_Update(&md,"yesnomaybe",10); SHA1_Update(&md,buf,strlen(buf)); SHA1_Final(digest,&md); //printf("The SHA1 of password is\n"); for(i=0;i<20;i++) { //printf("%02x",digest[i]); } //printf("\n"); /******************************************* COMPUTE SHA1 OF X AND RANDOM BITS(RB1) 1 *******************************************/ /* SHA1_Init(&md); SHA1_Update(&md,digest,20); SHA1_Update(&md,HW4_random_bits_1,20); SHA1_Final(X_RB1,&md); for(i=0;i<20;i++) { //printf("%02x",X_RB1[i]); } //printf("\n");*/ /****************************************** COMPUTE SHA1 OF RB1(Y) AND RANDOM BITS 2(RB2) ******************************************/ /* SHA1_Init(&md); SHA1_Update(&md,X_RB1,20); SHA1_Update(&md,HW4_random_bits_2,20); SHA1_Final(X_RB2,&md); for(i=0;i<20;i++) { //printf("%02x",X_RB2[i]); } //printf("\n");*/ /*************************************** COMPUTER IV AND 3 DES KEYS ***************************************/ // SC_3des_key_gen(NULL,digest,IV,DES_key1,DES_key2,DES_key3); SmartcardState pss=(SmartcardState)NULL; void *handle=NULL; //void *vp =NULL; SC_Init_Func *pfn_init=NULL; SC_Cleanup_Func *pfn_cleanup=NULL; SC_GetSignatureSize_Func *pfn_getsigsize=NULL; SC_3DesKeyGen_Func *pfn_sc_enc=NULL; handle = dlopen(sopath, RTLD_NOW|RTLD_GLOBAL); if (handle==NULL) { //fprintf(stderr, "%s\n",sopath); fprintf(stderr, "%s\n", dlerror()); fprintf(stderr,"dlopen() failed\n"); exit(1); } pfn_init = (SC_Init_Func*)dlsym(handle,"SC_init"); pfn_cleanup = (SC_Cleanup_Func*)dlsym(handle,"SC_cleanup"); pfn_getsigsize = (SC_GetSignatureSize_Func*)dlsym(handle,"SC_get_signature_size"); pfn_sc_enc = (SC_3DesKeyGen_Func *)dlsym(handle,"SC_3des_key_gen"); if(pfn_init==NULL || pfn_cleanup==NULL || pfn_getsigsize==NULL || pfn_sc_enc==NULL) { fprintf(stderr,"(cannot find smartcard functions in this library)\n"); exit(1); } pss = (pfn_init)(); //printf("sig size is %d\n", (pfn_getsigsize)(pss)); (pfn_sc_enc) (pss,digest,IV,DES_key1,DES_key2,DES_key3); (pfn_cleanup)(pss); dlclose(handle); /* for(i=0;i<8;i++) IV[i]=X_RB1[i]; for(i=8,j=0;i<16;i++,j++) DES_key1[j]=X_RB1[i]; for(i=0;i<8;i++) DES_key2[i]=X_RB2[i]; for(i=8,j=0;i<16;i++,j++) DES_key3[j]=X_RB2[i]; printf("IV="); for(i=0;i<8;i++) printf("%02x",IV[i]); printf("\nDES KEY 1="); for(i=0;i<8;i++) printf("%02x",DES_key1[i]); printf("\nDES key 2="); for(i=0;i<8;i++) printf("%02x",DES_key2[i]); printf("\nDES key 3="); for(i=0;i<8;i++) printf("%02x",DES_key3[i]); printf("\n");*/ DES_set_odd_parity((DES_cblock *)DES_key1); DES_set_odd_parity((DES_cblock *)DES_key2); DES_set_odd_parity((DES_cblock *)DES_key3); DES_key_sched((DES_cblock *)DES_key1,&schedule1); DES_set_key((DES_cblock *)DES_key1,&schedule1); DES_key_sched((DES_cblock *)DES_key2,&schedule2); DES_set_key((DES_cblock *)DES_key2,&schedule2); DES_key_sched((DES_cblock *)DES_key3,&schedule3); DES_set_key((DES_cblock *)DES_key3,&schedule3); /****************************************** READ FILE 8 BYTES AT A TIME AND ENCRYPT IT ******************************************/ if((fp=fopen(filename,"rb"))==NULL) { fprintf(stderr,"{input file %s does not exist}\n",filename); exit(1); } i=0; while((count=fread(&ch,1,1,fp))) { i++; } // printf("no. of bytes=%d\n",i); no_of_bytes=i%8; fclose(fp); printf("HW4"); if(no_of_bytes>0) printf("%c",no_of_bytes); else printf("%c",eight); if((fp=fopen(filename,"rb"))==NULL) { fprintf(stderr,"{input file %s does not exist}\n",filename); exit(1); } while((count=fread(&DES_input,1,8,fp))) { if(count!=8) { for(i=count;i<8;i++) DES_input[i]='\0'; DES_ede3_cbc_encrypt(DES_input,DES_output,8,&schedule1,&schedule2,&schedule3,(DES_cblock*)IV,1); for(i=0;i<8;i++) printf("%c",DES_output[i]); // printf("%s",DES_output); } else { // printf("%d\n",count); DES_ede3_cbc_encrypt(DES_input,DES_output,8,&schedule1,&schedule2,&schedule3,(DES_cblock*)IV,1); for(i=0;i<8;i++) printf("%c",DES_output[i]); // printf("%s",DES_output); } } for(i=0;i<20;i++) printf("%c",file_digest[i]); return 1; }
static int check(unsigned char *keydata, int ks) { // Decrypt first data block in order to check the first two bits of // the MPI. If they are correct, there's a good chance that the // password is correct, too. unsigned char ivec[32]; unsigned char out[BIG_ENOUGH * 2] = { 0 }; int tmp = 0; uint32_t num_bits; int checksumOk; int i; // Quick Hack memcpy(ivec, cur_salt->iv, blockSize(cur_salt->cipher_algorithm)); switch (cur_salt->cipher_algorithm) { case CIPHER_IDEA: { IDEA_KEY_SCHEDULE iks; JtR_idea_set_encrypt_key(keydata, &iks); JtR_idea_cfb64_encrypt(cur_salt->data, out, SALT_LENGTH, &iks, ivec, &tmp, IDEA_DECRYPT); } break; case CIPHER_CAST5: { CAST_KEY ck; CAST_set_key(&ck, ks, keydata); CAST_cfb64_encrypt(cur_salt->data, out, CAST_BLOCK, &ck, ivec, &tmp, CAST_DECRYPT); } break; case CIPHER_BLOWFISH: { BF_KEY ck; BF_set_key(&ck, ks, keydata); BF_cfb64_encrypt(cur_salt->data, out, BF_BLOCK, &ck, ivec, &tmp, BF_DECRYPT); } break; case CIPHER_AES128: case CIPHER_AES192: case CIPHER_AES256: { AES_KEY ck; AES_set_encrypt_key(keydata, ks * 8, &ck); AES_cfb128_encrypt(cur_salt->data, out, AES_BLOCK_SIZE, &ck, ivec, &tmp, AES_DECRYPT); } break; case CIPHER_3DES: { DES_cblock key1, key2, key3; DES_cblock divec; DES_key_schedule ks1, ks2, ks3; int num = 0; memcpy(key1, keydata + 0, 8); memcpy(key2, keydata + 8, 8); memcpy(key3, keydata + 16, 8); memcpy(divec, ivec, 8); DES_set_key((DES_cblock *)key1, &ks1); DES_set_key((DES_cblock *)key2, &ks2); DES_set_key((DES_cblock *)key3, &ks3); DES_ede3_cfb64_encrypt(cur_salt->data, out, SALT_LENGTH, &ks1, &ks2, &ks3, &divec, &num, DES_DECRYPT); } break; default: printf("(check) Unknown Cipher Algorithm %d ;(\n", cur_salt->cipher_algorithm); break; } num_bits = ((out[0] << 8) | out[1]); if (num_bits < MIN_BN_BITS || num_bits > cur_salt->bits) { return 0; } // Decrypt all data memcpy(ivec, cur_salt->iv, blockSize(cur_salt->cipher_algorithm)); tmp = 0; switch (cur_salt->cipher_algorithm) { case CIPHER_IDEA: { IDEA_KEY_SCHEDULE iks; JtR_idea_set_encrypt_key(keydata, &iks); JtR_idea_cfb64_encrypt(cur_salt->data, out, cur_salt->datalen, &iks, ivec, &tmp, IDEA_DECRYPT); } break; case CIPHER_CAST5: { CAST_KEY ck; CAST_set_key(&ck, ks, keydata); CAST_cfb64_encrypt(cur_salt->data, out, cur_salt->datalen, &ck, ivec, &tmp, CAST_DECRYPT); } break; case CIPHER_BLOWFISH: { BF_KEY ck; BF_set_key(&ck, ks, keydata); BF_cfb64_encrypt(cur_salt->data, out, cur_salt->datalen, &ck, ivec, &tmp, BF_DECRYPT); } break; case CIPHER_AES128: case CIPHER_AES192: case CIPHER_AES256: { AES_KEY ck; AES_set_encrypt_key(keydata, ks * 8, &ck); AES_cfb128_encrypt(cur_salt->data, out, cur_salt->datalen, &ck, ivec, &tmp, AES_DECRYPT); } break; case CIPHER_3DES: { DES_cblock key1, key2, key3; DES_cblock divec; DES_key_schedule ks1, ks2, ks3; int num = 0; memcpy(key1, keydata + 0, 8); memcpy(key2, keydata + 8, 8); memcpy(key3, keydata + 16, 8); memcpy(divec, ivec, 8); DES_set_key((DES_cblock *) key1, &ks1); DES_set_key((DES_cblock *) key2, &ks2); DES_set_key((DES_cblock *) key3, &ks3); DES_ede3_cfb64_encrypt(cur_salt->data, out, cur_salt->datalen, &ks1, &ks2, &ks3, &divec, &num, DES_DECRYPT); } break; default: break; } // Verify checksumOk = 0; switch (cur_salt->usage) { case 254: { uint8_t checksum[SHA_DIGEST_LENGTH]; SHA_CTX ctx; SHA1_Init(&ctx); SHA1_Update(&ctx, out, cur_salt->datalen - SHA_DIGEST_LENGTH); SHA1_Final(checksum, &ctx); if (memcmp(checksum, out + cur_salt->datalen - SHA_DIGEST_LENGTH, SHA_DIGEST_LENGTH) == 0) return 1; /* we have a 20 byte verifier ;) */ else return 0; } break; case 0: case 255: { // https://tools.ietf.org/html/rfc4880#section-3.7.2 uint16_t sum = 0; for (i = 0; i < cur_salt->datalen - 2; i++) { sum += out[i]; } if (sum == ((out[cur_salt->datalen - 2] << 8) | out[cur_salt->datalen - 1])) { checksumOk = 1; } } break; default: break; } // If the checksum is ok, try to parse the first MPI of the private key // Stop relying on checksum altogether, GnuPG ignores it (after // documenting why though!) if (checksumOk) { BIGNUM *b = NULL; uint32_t blen = (num_bits + 7) / 8; int ret; if (cur_salt->datalen == 24 && blen != 20) /* verifier 1 */ return 0; if (blen < cur_salt->datalen && ((b = BN_bin2bn(out + 2, blen, NULL)) != NULL)) { char *str = BN_bn2hex(b); DSA dsa; ElGamal_secret_key elg; RSA_secret_key rsa; if (strlen(str) != blen * 2) { /* verifier 2 */ OPENSSL_free(str); return 0; } OPENSSL_free(str); if (cur_salt->pk_algorithm == 17) { /* DSA check */ dsa.p = BN_bin2bn(cur_salt->p, cur_salt->pl, NULL); // puts(BN_bn2hex(dsa.p)); dsa.q = BN_bin2bn(cur_salt->q, cur_salt->ql, NULL); // puts(BN_bn2hex(dsa.q)); dsa.g = BN_bin2bn(cur_salt->g, cur_salt->gl, NULL); // puts(BN_bn2hex(dsa.g)); dsa.priv_key = b; dsa.pub_key = BN_bin2bn(cur_salt->y, cur_salt->yl, NULL); // puts(BN_bn2hex(dsa.pub_key)); ret = check_dsa_secret_key(&dsa); /* verifier 3 */ if (ret != 0) return 0; } if (cur_salt->pk_algorithm == 16 || cur_salt->pk_algorithm == 20) { /* ElGamal check */ elg.p = BN_bin2bn(cur_salt->p, cur_salt->pl, NULL); // puts(BN_bn2hex(elg.p)); elg.g = BN_bin2bn(cur_salt->g, cur_salt->gl, NULL); // puts(BN_bn2hex(elg.g)); elg.x = b; // puts(BN_bn2hex(elg.x)); elg.y = BN_bin2bn(cur_salt->y, cur_salt->yl, NULL); // puts(BN_bn2hex(elg.y)); ret = check_elg_secret_key(&elg); /* verifier 3 */ if (ret != 0) return 0; } if (cur_salt->pk_algorithm == 1) { /* RSA check */ // http://www.ietf.org/rfc/rfc4880.txt int length = 0; length += give_multi_precision_integer(out, length, &cur_salt->dl, cur_salt->d); length += give_multi_precision_integer(out, length, &cur_salt->pl, cur_salt->p); length += give_multi_precision_integer(out, length, &cur_salt->ql, cur_salt->q); rsa.n = BN_bin2bn(cur_salt->n, cur_salt->nl, NULL); rsa.p = BN_bin2bn(cur_salt->p, cur_salt->pl, NULL); rsa.q = BN_bin2bn(cur_salt->q, cur_salt->ql, NULL); ret = check_rsa_secret_key(&rsa); if (ret != 0) return 0; } return 1; } } return 0; }
static int cuda_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { switch ((ctx->cipher)->nid) { case NID_des_ecb: case NID_des_cbc: if (!quiet && verbose) fprintf(stdout,"Start calculating DES key schedule..."); DES_key_schedule des_key_schedule; DES_set_key((const_DES_cblock *)key,&des_key_schedule); DES_cuda_transfer_key_schedule(&des_key_schedule); if(iv) DES_cuda_transfer_iv(iv); break; case NID_bf_ecb: case NID_bf_cbc: if (!quiet && verbose) fprintf(stdout,"Start calculating Blowfish key schedule...\n"); BF_KEY key_schedule; BF_set_key(&key_schedule,ctx->key_len,key); BF_cuda_transfer_key_schedule(&key_schedule); if(iv) BF_cuda_transfer_iv(iv); break; case NID_cast5_ecb: case NID_cast5_cbc: if (!quiet && verbose) fprintf(stdout,"Start calculating CAST5 key schedule...\n"); CAST_KEY cast_key_schedule; CAST_set_key(&cast_key_schedule,ctx->key_len*8,key); CAST_cuda_transfer_key_schedule(&cast_key_schedule); if(iv) CAST_cuda_transfer_iv(iv); break; case NID_camellia_128_ecb: case NID_camellia_128_cbc: if (!quiet && verbose) fprintf(stdout,"Start calculating Camellia key schedule...\n"); CAMELLIA_KEY cmll_key_schedule; Camellia_set_key(key,ctx->key_len*8,&cmll_key_schedule); CMLL_cuda_transfer_key_schedule(&cmll_key_schedule); if(iv) CMLL_cuda_transfer_iv(iv); break; case NID_idea_ecb: case NID_idea_cbc: if (!quiet && verbose) fprintf(stdout,"Start calculating IDEA key schedule...\n"); { IDEA_KEY_SCHEDULE idea_key_schedule, idea_dec_key_schedule; idea_set_encrypt_key(key,&idea_key_schedule); if(!(ctx->encrypt)) { idea_set_decrypt_key(&idea_key_schedule,&idea_dec_key_schedule); IDEA_cuda_transfer_key_schedule(&idea_dec_key_schedule); } else { IDEA_cuda_transfer_key_schedule(&idea_key_schedule); } } if(iv) IDEA_cuda_transfer_iv(iv); break; case NID_aes_128_ecb: case NID_aes_128_cbc: { if (!quiet && verbose) fprintf(stdout,"Start calculating AES-128 key schedule...\n"); AES_KEY aes_key_schedule; if(ctx->encrypt) AES_cuda_set_encrypt_key(key,128,&aes_key_schedule); else AES_cuda_set_decrypt_key(key,128,&aes_key_schedule); AES_cuda_transfer_key_schedule(&aes_key_schedule); } if(iv) AES_cuda_transfer_iv(iv); break; case NID_aes_192_ecb: case NID_aes_192_cbc: if (!quiet && verbose) fprintf(stdout,"Start calculating AES-192 key schedule...\n"); { AES_KEY aes_key_schedule; if(ctx->encrypt) AES_cuda_set_encrypt_key(key,192,&aes_key_schedule); else AES_cuda_set_decrypt_key(key,192,&aes_key_schedule); AES_cuda_transfer_key_schedule(&aes_key_schedule); if(iv) AES_cuda_transfer_iv(iv); } break; case NID_aes_256_ecb: case NID_aes_256_cbc: if (!quiet && verbose) fprintf(stdout,"Start calculating AES-256 key schedule...\n"); { AES_KEY aes_key_schedule; if(ctx->encrypt) AES_cuda_set_encrypt_key(key,256,&aes_key_schedule); else AES_cuda_set_decrypt_key(key,256,&aes_key_schedule); AES_cuda_transfer_key_schedule(&aes_key_schedule); if(iv) AES_cuda_transfer_iv(iv); } break; default: return 0; } if (!quiet && verbose) fprintf(stdout,"DONE!\n"); return 1; }
odp_bool_t verify_ipv4_packet(stream_db_entry_t *stream, odp_packet_t pkt) { ipsec_cache_entry_t *entry = NULL; uint8_t *data; odph_ipv4hdr_t *ip; odph_ahhdr_t *ah = NULL; odph_esphdr_t *esp = NULL; int hdr_len; odph_icmphdr_t *icmp; stream_pkt_hdr_t *test; uint32_t src_ip, dst_ip; if (stream->input.entry) entry = stream->input.entry; else if (stream->output.entry) entry = stream->output.entry; /* Basic IPv4 verify (add checksum verification) */ data = odp_packet_l3_ptr(pkt, NULL); ip = (odph_ipv4hdr_t *)data; data += sizeof(*ip); if (0x45 != ip->ver_ihl) return FALSE; src_ip = odp_be_to_cpu_32(ip->src_addr); dst_ip = odp_be_to_cpu_32(ip->dst_addr); if ((stream->src_ip != src_ip) && stream->output.entry && (stream->output.entry->tun_src_ip != src_ip)) return FALSE; if ((stream->dst_ip != dst_ip) && stream->output.entry && (stream->output.entry->tun_dst_ip != dst_ip)) return FALSE; if ((stream->src_ip != src_ip) && stream->input.entry && (stream->input.entry->tun_src_ip != src_ip)) return FALSE; if ((stream->dst_ip != dst_ip) && stream->input.entry && (stream->input.entry->tun_dst_ip != dst_ip)) return FALSE; /* Find IPsec headers if any and compare against entry */ hdr_len = locate_ipsec_headers(ip, &ah, &esp); /* Cleartext packet */ if (!ah && !esp) goto clear_packet; if (ah) { if (!entry) return FALSE; if (ODP_AUTH_ALG_NULL == entry->ah.alg) return FALSE; if (odp_be_to_cpu_32(ah->spi) != entry->ah.spi) return FALSE; if (ODP_AUTH_ALG_MD5_96 != entry->ah.alg) abort(); } else { if (entry && (ODP_AUTH_ALG_NULL != entry->ah.alg)) return FALSE; } if (esp) { if (!entry) return FALSE; if (ODP_CIPHER_ALG_NULL == entry->esp.alg) return FALSE; if (odp_be_to_cpu_32(esp->spi) != entry->esp.spi) return FALSE; if (ODP_CIPHER_ALG_3DES_CBC != entry->esp.alg) abort(); hdr_len += entry->esp.iv_len; } else { if (entry && (ODP_CIPHER_ALG_NULL != entry->esp.alg)) return FALSE; } data += hdr_len; /* Verify authentication (if present) */ if (ah) { uint8_t ip_tos; uint8_t ip_ttl; uint16_t ip_frag_offset; uint8_t icv[12]; uint8_t hash[EVP_MAX_MD_SIZE]; /* Save/clear mutable fields */ ip_tos = ip->tos; ip_ttl = ip->ttl; ip_frag_offset = odp_be_to_cpu_16(ip->frag_offset); ip->tos = 0; ip->ttl = 0; ip->frag_offset = 0; ip->chksum = 0; memcpy(icv, ah->icv, 12); memset(ah->icv, 0, 12); /* Calculate HMAC and compare */ HMAC(EVP_md5(), entry->ah.key.data, entry->ah.key.length, (uint8_t *)ip, odp_be_to_cpu_16(ip->tot_len), hash, NULL); if (0 != memcmp(icv, hash, sizeof(icv))) return FALSE; ip->proto = ah->next_header; ip->tos = ip_tos; ip->ttl = ip_ttl; ip->frag_offset = odp_cpu_to_be_16(ip_frag_offset); } /* Decipher if present */ if (esp) { odph_esptrl_t *esp_t; DES_key_schedule ks1, ks2, ks3; uint8_t iv[8]; int encrypt_len = ipv4_data_len(ip) - hdr_len; memcpy(iv, esp->iv, sizeof(iv)); DES_set_key((DES_cblock *)&entry->esp.key.data[0], &ks1); DES_set_key((DES_cblock *)&entry->esp.key.data[8], &ks2); DES_set_key((DES_cblock *)&entry->esp.key.data[16], &ks3); DES_ede3_cbc_encrypt((uint8_t *)data, (uint8_t *)data, encrypt_len, &ks1, &ks2, &ks3, (DES_cblock *)iv, 0); esp_t = (odph_esptrl_t *)(data + encrypt_len) - 1; ip->proto = esp_t->next_header; } clear_packet: /* Verify IP/ICMP packet */ if (entry && (entry->mode == IPSEC_SA_MODE_TUNNEL) && (ah || esp)) { if (ODPH_IPV4 != ip->proto) return FALSE; odph_ipv4hdr_t *inner_ip = (odph_ipv4hdr_t *)data; icmp = (odph_icmphdr_t *)(inner_ip + 1); data = (uint8_t *)icmp; } else { if (ODPH_IPPROTO_ICMP != ip->proto) return FALSE; icmp = (odph_icmphdr_t *)data; } /* Verify ICMP header */ data += sizeof(*icmp); if (ICMP_ECHO != icmp->type) return FALSE; if (0x1234 != odp_be_to_cpu_16(icmp->un.echo.id)) return FALSE; /* Now check our packet */ test = (stream_pkt_hdr_t *)data; if (STREAM_MAGIC != odp_be_to_cpu_64(test->magic)) return FALSE; return TRUE; }
odp_packet_t create_ipv4_packet(stream_db_entry_t *stream, uint8_t *dmac, odp_pool_t pkt_pool) { ipsec_cache_entry_t *entry = NULL; odp_packet_t pkt; uint8_t *base; uint8_t *data; odph_ethhdr_t *eth; odph_ipv4hdr_t *ip; odph_ipv4hdr_t *inner_ip = NULL; odph_ahhdr_t *ah = NULL; odph_esphdr_t *esp = NULL; odph_icmphdr_t *icmp; stream_pkt_hdr_t *test; unsigned i; if (stream->input.entry) entry = stream->input.entry; else if (stream->output.entry) entry = stream->output.entry; /* Get packet */ pkt = odp_packet_alloc(pkt_pool, 0); if (ODP_PACKET_INVALID == pkt) return ODP_PACKET_INVALID; base = odp_packet_data(pkt); data = odp_packet_data(pkt); /* Ethernet */ odp_packet_has_eth_set(pkt, 1); eth = (odph_ethhdr_t *)data; data += sizeof(*eth); memset((char *)eth->src.addr, (0x80 | stream->id), ODPH_ETHADDR_LEN); memcpy((char *)eth->dst.addr, dmac, ODPH_ETHADDR_LEN); eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); /* IPv4 */ odp_packet_has_ipv4_set(pkt, 1); ip = (odph_ipv4hdr_t *)data; data += sizeof(*ip); /* Wait until almost finished to fill in mutable fields */ memset((char *)ip, 0, sizeof(*ip)); ip->ver_ihl = 0x45; ip->id = odp_cpu_to_be_16(stream->id); /* Outer IP header in tunnel mode */ if (entry && entry->mode == IPSEC_SA_MODE_TUNNEL && (entry == stream->input.entry)) { ip->proto = ODPH_IPV4; ip->src_addr = odp_cpu_to_be_32(entry->tun_src_ip); ip->dst_addr = odp_cpu_to_be_32(entry->tun_dst_ip); } else { ip->proto = ODPH_IPPROTO_ICMP; ip->src_addr = odp_cpu_to_be_32(stream->src_ip); ip->dst_addr = odp_cpu_to_be_32(stream->dst_ip); } /* AH (if specified) */ if (entry && (entry == stream->input.entry) && (ODP_AUTH_ALG_NULL != entry->ah.alg)) { if (ODP_AUTH_ALG_MD5_96 != entry->ah.alg) abort(); ah = (odph_ahhdr_t *)data; data += sizeof(*ah); data += entry->ah.icv_len; memset((char *)ah, 0, sizeof(*ah) + entry->ah.icv_len); ah->ah_len = 1 + (entry->ah.icv_len / 4); ah->spi = odp_cpu_to_be_32(entry->ah.spi); ah->seq_no = odp_cpu_to_be_32(stream->input.ah_seq++); } /* ESP (if specified) */ if (entry && (entry == stream->input.entry) && (ODP_CIPHER_ALG_NULL != entry->esp.alg)) { if (ODP_CIPHER_ALG_3DES_CBC != entry->esp.alg) abort(); esp = (odph_esphdr_t *)data; data += sizeof(*esp); data += entry->esp.iv_len; esp->spi = odp_cpu_to_be_32(entry->esp.spi); esp->seq_no = odp_cpu_to_be_32(stream->input.esp_seq++); RAND_bytes(esp->iv, 8); } /* Inner IP header in tunnel mode */ if (entry && (entry == stream->input.entry) && (entry->mode == IPSEC_SA_MODE_TUNNEL)) { inner_ip = (odph_ipv4hdr_t *)data; memset((char *)inner_ip, 0, sizeof(*inner_ip)); inner_ip->ver_ihl = 0x45; inner_ip->proto = ODPH_IPPROTO_ICMP; inner_ip->id = odp_cpu_to_be_16(stream->id); inner_ip->ttl = 64; inner_ip->tos = 0; inner_ip->frag_offset = 0; inner_ip->src_addr = odp_cpu_to_be_32(stream->src_ip); inner_ip->dst_addr = odp_cpu_to_be_32(stream->dst_ip); inner_ip->chksum = odp_chksum(inner_ip, sizeof(*inner_ip)); data += sizeof(*inner_ip); } /* ICMP header so we can see it on wireshark */ icmp = (odph_icmphdr_t *)data; data += sizeof(*icmp); icmp->type = ICMP_ECHO; icmp->code = 0; icmp->un.echo.id = odp_cpu_to_be_16(0x1234); icmp->un.echo.sequence = odp_cpu_to_be_16(stream->created); /* Packet payload of incrementing bytes */ test = (stream_pkt_hdr_t *)data; data += sizeof(*test); test->magic = odp_cpu_to_be_64(STREAM_MAGIC); for (i = 0; i < stream->length; i++) *data++ = (uint8_t)i; /* Close ICMP */ icmp->chksum = 0; icmp->chksum = odp_chksum(icmp, data - (uint8_t *)icmp); /* Close ESP if specified */ if (esp) { int payload_len = data - (uint8_t *)icmp; uint8_t *encrypt_start = (uint8_t *)icmp; if (entry->mode == IPSEC_SA_MODE_TUNNEL) { payload_len = data - (uint8_t *)inner_ip; encrypt_start = (uint8_t *)inner_ip; } int encrypt_len; odph_esptrl_t *esp_t; DES_key_schedule ks1, ks2, ks3; uint8_t iv[8]; memcpy(iv, esp->iv, sizeof(iv)); encrypt_len = ESP_ENCODE_LEN(payload_len + sizeof(*esp_t), entry->esp.block_len); memset(data, 0, encrypt_len - payload_len); data += encrypt_len - payload_len; esp_t = (odph_esptrl_t *)(data) - 1; esp_t->pad_len = encrypt_len - payload_len - sizeof(*esp_t); esp_t->next_header = ip->proto; ip->proto = ODPH_IPPROTO_ESP; DES_set_key((DES_cblock *)&entry->esp.key.data[0], &ks1); DES_set_key((DES_cblock *)&entry->esp.key.data[8], &ks2); DES_set_key((DES_cblock *)&entry->esp.key.data[16], &ks3); DES_ede3_cbc_encrypt(encrypt_start, encrypt_start, encrypt_len, &ks1, &ks2, &ks3, (DES_cblock *)iv, 1); } /* Since ESP can pad we can now fix IP length */ ip->tot_len = odp_cpu_to_be_16(data - (uint8_t *)ip); /* Close AH if specified */ if (ah) { uint8_t hash[EVP_MAX_MD_SIZE]; int auth_len = data - (uint8_t *)ip; ah->next_header = ip->proto; ip->proto = ODPH_IPPROTO_AH; HMAC(EVP_md5(), entry->ah.key.data, entry->ah.key.length, (uint8_t *)ip, auth_len, hash, NULL); memcpy(ah->icv, hash, 12); } /* Correct set packet length offsets */ odp_packet_push_tail(pkt, data - base); odp_packet_l2_offset_set(pkt, (uint8_t *)eth - base); odp_packet_l3_offset_set(pkt, (uint8_t *)ip - base); odp_packet_l4_offset_set(pkt, ((uint8_t *)ip - base) + sizeof(*ip)); /* Now fill in final IP header fields */ ip->ttl = 64; ip->tos = 0; ip->frag_offset = 0; ip->chksum = 0; odph_ipv4_csum_update(pkt); return pkt; }
void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2) { DES_key_schedule ks; int i,length; register unsigned char j; TINYCLR_SSL_MEMSET(key1,0,8); TINYCLR_SSL_MEMSET(key2,0,8); length=TINYCLR_SSL_STRLEN(str); #ifdef OLD_STR_TO_KEY if (length <= 8) { for (i=0; i<length; i++) { (*key2)[i]=(*key1)[i]=(str[i]<<1); } } else { for (i=0; i<length; i++) { if ((i/8)&1) (*key2)[i%8]^=(str[i]<<1); else (*key1)[i%8]^=(str[i]<<1); } } #else /* MIT COMPATIBLE */ for (i=0; i<length; i++) { j=str[i]; if ((i%32) < 16) { if ((i%16) < 8) (*key1)[i%8]^=(j<<1); else (*key2)[i%8]^=(j<<1); } else { j=((j<<4)&0xf0)|((j>>4)&0x0f); j=((j<<2)&0xcc)|((j>>2)&0x33); j=((j<<1)&0xaa)|((j>>1)&0x55); if ((i%16) < 8) (*key1)[7-(i%8)]^=j; else (*key2)[7-(i%8)]^=j; } } if (length <= 8) TINYCLR_SSL_MEMCPY(key2,key1,8); #endif DES_set_odd_parity(key1); DES_set_odd_parity(key2); #ifdef EXPERIMENTAL_STR_TO_STRONG_KEY if(DES_is_weak_key(key1)) (*key1)[7] ^= 0xF0; DES_set_key(key1,&ks); #else DES_set_key_unchecked(key1,&ks); #endif DES_cbc_cksum((const unsigned char*)str,key1,length,&ks,key1); #ifdef EXPERIMENTAL_STR_TO_STRONG_KEY if(DES_is_weak_key(key2)) (*key2)[7] ^= 0xF0; DES_set_key(key2,&ks); #else DES_set_key_unchecked(key2,&ks); #endif DES_cbc_cksum((const unsigned char*)str,key2,length,&ks,key2); OPENSSL_cleanse(&ks,sizeof(ks)); DES_set_odd_parity(key1); DES_set_odd_parity(key2); }
int CmdHF14AMfDESAuth(const char *Cmd){ uint8_t blockNo = 0; //keyNo=0; uint32_t cuid=0; uint8_t reply[16]; //DES_cblock r1_b1; uint8_t b1[8]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t b2[8]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; DES_cblock nr, b0, r1, r0; uint8_t key[8]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //DES_cblock iv={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; DES_key_schedule ks1; DES_cblock key1; if (strlen(Cmd)<1) { PrintAndLog("Usage: hf desfire des-auth k <key number>"); PrintAndLog(" sample: hf desfire des-auth k 0"); return 0; } //Change key to user defined one memcpy(key1,key,8); //memcpy(key2,key+8,8); DES_set_key((DES_cblock *)key1,&ks1); //DES_set_key((DES_cblock *)key2,&ks2); //Auth1 UsbCommand c = {CMD_MIFARE_DES_AUTH1, {blockNo}}; SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { uint8_t isOK = resp.arg[0] & 0xff; cuid = resp.arg[1]; uint8_t * data= resp.d.asBytes; if (isOK){ PrintAndLog("enc(nc)/b0:%s", sprint_hex(data+2,8)); memcpy(b0,data+2,8); } } else { PrintAndLog("Command execute timeout"); } //Do crypto magic DES_random_key(&nr); //b1=dec(nr) //r0=dec(b0) DES_ecb_encrypt(&nr,&b1,&ks1,0); DES_ecb_encrypt(&b0,&r0,&ks1,0); //PrintAndLog("b1:%s",sprint_hex(b1, 8)); PrintAndLog("r0:%s",sprint_hex(r0, 8)); //r1=rol(r0) memcpy(r1,r0,8); rol(r1,8); PrintAndLog("r1:%s",sprint_hex(r1, 8)); for(int i=0;i<8;i++){ b2[i]=(r1[i] ^ b1[i]); } DES_ecb_encrypt(&b2,&b2,&ks1,0); //PrintAndLog("b1:%s",sprint_hex(b1, 8)); PrintAndLog("b2:%s",sprint_hex(b2, 8)); //Auth2 UsbCommand d = {CMD_MIFARE_DES_AUTH2, {cuid}}; memcpy(reply,b1,8); memcpy(reply+8,b2,8); memcpy(d.d.asBytes,reply, 16); SendCommand(&d); UsbCommand respb; if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) { uint8_t isOK = respb.arg[0] & 0xff; uint8_t * data2= respb.d.asBytes; if (isOK){ PrintAndLog("b3:%s", sprint_hex(data2+2, 8)); } } else { PrintAndLog("Command execute timeout"); } return 1; }
static int cardos_sm4h(const unsigned char *in, size_t inlen, unsigned char *out, size_t outlen, const unsigned char *key, size_t keylen) { /* using a buffer with an APDU, build an SM 4h APDU for cardos */ int plain_lc; /* data size in orig APDU */ unsigned int mac_input_len, enc_input_len; unsigned char *mac_input, *enc_input; DES_key_schedule ks_a, ks_b; DES_cblock des_in,des_out; unsigned int i,j; if (keylen != 16) { printf("key has wrong size, need 16 bytes, got %zd. aborting.\n", keylen); return 0; } if (inlen < 4) return 0; /* failed, apdu too short */ if (inlen <= 5) plain_lc = 0; if (inlen > 5) plain_lc = in[4]; /* 4 + plain_lc plus 0..7 bytes of padding */ mac_input_len = 4 + plain_lc; while (mac_input_len % 8) mac_input_len++; mac_input = calloc(1,mac_input_len); if (!mac_input) { printf("out of memory, aborting\n"); return 0; } mac_input[0] = in[1]; /* ins */ mac_input[1] = in[2]; /* p1 */ mac_input[2] = in[3]; /* p2 */ mac_input[3] = plain_lc + 8; if (plain_lc) /* copy data from in APDU */ memcpy(&mac_input[4],&in[5],plain_lc); /* calloc already did the ansi padding: rest is 00 */ /* prepare des key using first 8 bytes of key */ DES_set_key((const_DES_cblock*) &key[0], &ks_a); /* prepare des key using second 8 bytes of key */ DES_set_key((const_DES_cblock*) &key[8], &ks_b); /* first block: XOR with IV and encrypt with key A IV is 8 bytes 00 */ for (i=0; i < 8; i++) des_in[i] = mac_input[i]^00; DES_ecb_encrypt(&des_in, &des_out, &ks_a, 1); /* all other blocks: XOR with prev. result and encrypt with key A */ for (j=1; j < (mac_input_len / 8); j++) { for (i=0; i < 8; i++) des_in[i] = mac_input[i+j*8]^des_out[i]; DES_ecb_encrypt(&des_in, &des_out, &ks_a, 1); } /* now decrypt with key B and encrypt with key A again */ /* (a noop if key A and B are the same, e.g. 8 bytes ff */ for (i=0; i < 8; i++) des_in[i] = des_out[i]; DES_ecb_encrypt(&des_in, &des_out, &ks_b, 0); for (i=0; i < 8; i++) des_in[i] = des_out[i]; DES_ecb_encrypt(&des_in, &des_out, &ks_a, 1); /* now we want to enc: * orig APDU data plus mac (8 bytes) plus iso padding (1-8 bytes) */ enc_input_len = plain_lc + 8 + 1; while (enc_input_len % 8) enc_input_len++; enc_input = calloc(1,enc_input_len); if (!enc_input) { free(mac_input); printf("out of memory, aborting\n"); return 0; } if (plain_lc) memcpy(&enc_input[0],&in[5],plain_lc); for (i=0; i < 8; i++) enc_input[i+plain_lc] = des_out[i]; enc_input[plain_lc+8] = 0x80; /* iso padding */ /* calloc already cleard the remaining bytes to 00 */ if (outlen < 5 + enc_input_len) { free(mac_input); free(enc_input); printf("output buffer too small, aborting.\n"); return 0; } out[0] = in[0]; /* cla */ out[1] = in[1]; /* ins */ out[2] = in[2]; /* p1 */ out[3] = in[3]; /* p2 */ out[4] = enc_input_len; /* lc */ /* encrypt first block */ /* xor data and IV (8 bytes 00) to get input data */ for (i=0; i < 8; i++) des_in[i] = enc_input[i] ^ 00; /* encrypt with des2 (tripple des, but using keys A-B-A) */ DES_ecb2_encrypt(&des_in, &des_out, &ks_a, &ks_b, 1); /* copy encrypted bytes into output */ for (i=0; i < 8; i++) out[5+i] = des_out[i]; /* encrypt other blocks (usualy one) */ for (j=1; j < (enc_input_len / 8); j++) { /* xor data and prev. result to get input data */ for (i=0; i < 8; i++) des_in[i] = enc_input[i+j*8] ^ des_out[i]; /* encrypt with des2 (tripple des, but using keys A-B-A) */ DES_ecb2_encrypt(&des_in, &des_out, &ks_a, &ks_b, 1); /* copy encrypted bytes into output */ for (i=0; i < 8; i++) out[5+8*j+i] = des_out[i]; } if (verbose) { printf ("Unencrypted APDU:\n"); util_hex_dump_asc(stdout, in, inlen, -1); printf ("Encrypted APDU:\n"); util_hex_dump_asc(stdout, out, out[4] + 5, -1); printf ("\n"); } free(mac_input); free(enc_input); return 1; }