void ecb(FILE* inf, FILE* keyf, DES_key_schedule klucz, int tryb) { printf("\n--- dzialania w trybie ECB...\n"); FILE* outf = fopen("plik.out", "w"); int i=0; DES_cblock in, out; if(tryb) { fwrite((void*)&klucz, sizeof(unsigned char), sizeof(DES_key_schedule), keyf); while((i=fread(&in, sizeof(unsigned char), 8, inf))==8) { DES_ecb_encrypt(&in, &out, &klucz, 1); fwrite(&out, sizeof(unsigned char), 8, outf); } if(i) { while(i<8) in[i++]='\0'; DES_ecb_encrypt(&in, &out, &klucz, 1); fwrite(&out, sizeof(unsigned char), 8, outf); } } else { fread((void*)&klucz, sizeof(unsigned char), sizeof(DES_key_schedule), keyf); while((i=fread(&in, sizeof(unsigned char), 8, inf))==8) { DES_ecb_encrypt(&in, &out, &klucz, 0); fwrite(&out, sizeof(unsigned char), 8, outf); } if(i) { while(i<8) in[i++]='\0'; DES_ecb_encrypt(&in, &out, &klucz, 0); fwrite(&out, sizeof(unsigned char), 8, outf); } } fclose(outf); }
void des::decrypt(char const* key, core::vector<byte> const& in, core::string& out) { DES_cblock key_block; DES_key_schedule schedule; DES_string_to_key(key, &key_block); DES_set_key_checked(&key_block, &schedule); char* buf = (char*)malloc(in.size()); core::vector<byte>::const_iterator iter = in.begin(); DES_cblock* output = (DES_cblock*)buf; DES_cblock input; while (iter != in.end()) { usize sz = in.end() - iter; if (sz >= 8) sz = 8; else memset(input, 0, sizeof(DES_cblock)); memcpy(input, &*iter, sz); DES_ecb_encrypt(&input, output, &schedule, DES_DECRYPT); iter += sz; output += 1; } out = buf; free(buf); }
int ofb64_decrypt(int data) { struct stinfo *stp = &fb[OFB].streams[DIR_DECRYPT-1]; int index; if (data == -1) { /* * Back up one byte. It is assumed that we will * never back up more than one byte. If we do, this * may or may not work. */ if (stp->str_index) --stp->str_index; return(0); } index = stp->str_index++; if (index == sizeof(DES_cblock)) { DES_cblock b; DES_ecb_encrypt(&stp->str_feed,&b,&stp->str_sched, 1); memcpy(stp->str_feed, b, sizeof(DES_cblock)); stp->str_index = 1; /* Next time will be 1 */ index = 0; /* But now use 0 */ } return(data ^ stp->str_feed[index]); }
void openssl_des_crypt() { int size; DES_cblock key; DES_cblock outputs; const_DES_cblock inputs; DES_key_schedule schedule; unsigned char tmp[16] = "des crypt"; DES_random_key(&key); DES_string_to_key("beike2012", &key); DES_set_odd_parity(&key); des_check_key_parity(&key); DES_set_key_checked(&key, &schedule); DES_is_weak_key((const_DES_cblock *)tmp); DES_ecb_encrypt((const_DES_cblock *)tmp, &outputs, &schedule, DES_ENCRYPT); printf("\nDES_ecb_encrypt(%s) = ", tmp); for (size = 0; size < sizeof(outputs); size++) printf("%02x", outputs[size]); printf("\n"); DES_ecb_encrypt(&outputs, &inputs, &schedule, DES_DECRYPT); printf("DES_ecb_decrypt("); for (size = 0; size < sizeof(outputs); size++) printf("%02x", outputs[size]); printf(") = %s\n", inputs); }
int main(int argc,char **argv) { DES_cblock key; /* DES_random_key(&key); */ /* generate a random key */ DES_string_to_key("pass", &key); DES_key_schedule schedule; DES_set_key_checked(&key, &schedule); const_DES_cblock input = "hehehe"; DES_cblock output; printf("cleartext:%s ", input); printf("\r\n "); DES_ecb_encrypt(&input, &output, &schedule, DES_ENCRYPT); printf("Encrypted! "); printf("ciphertext:"); int i; for (i = 0; i < sizeof(input); i++) printf("%02x", output[i]); printf("\r\n "); DES_ecb_encrypt(&output, &input, &schedule, DES_DECRYPT); printf("Decrypted! "); printf("cleartext:%s ", input); printf("\r\n "); return 0; }
void cIrdeto2::DES3(unsigned char *data, int mode) { int m1, m2; if(mode) { m1=DES_DECRYPT; m2=DES_ENCRYPT; } else { m1=DES_ENCRYPT; m2=DES_DECRYPT; } DES_ecb_encrypt((DES_cblock *)data,(DES_cblock *)data,&ks1,m1); DES_ecb_encrypt((DES_cblock *)data,(DES_cblock *)data,&ks2,m2); DES_ecb_encrypt((DES_cblock *)data,(DES_cblock *)data,&ks1,m1); }
crypto_error_t crypto_mac(bytestring_t *dst, const bytestring_t *ctx, const bytestring_t *src) { unsigned u,v; unsigned char tmp[8]; unsigned char clr[8]; unsigned char alg; crypto_error_t retval; bytestring_t *padded_src; DES_key_schedule key_schedule; DES_key_schedule key_schedule2; bytestring_get_element(&alg,ctx,0); if (alg==CRYPTO_ALG_ISO9797_M3) { padded_src = bytestring_new(8); retval = crypto_pad(padded_src,ctx,src); if (retval!=CRYPTO_OK) { bytestring_free(padded_src); return retval; } memset(tmp,0,8); memcpy(&key_schedule,ctx->data+KS_HEADER_SIZE,DES_KS_SIZE); memcpy(&key_schedule2,ctx->data+KS_HEADER_SIZE+DES_KS_SIZE,DES_KS_SIZE); for (u=0; u<bytestring_get_size(padded_src)/8; u++) { for (v=0; v<8; v++) clr[v]=padded_src->data[u*8+v]^tmp[v]; DES_ecb_encrypt((const_DES_cblock *)clr, (DES_cblock *)tmp, &key_schedule, DES_ENCRYPT); } memcpy(clr,tmp,8); DES_ecb_encrypt((const_DES_cblock *)clr, (DES_cblock *)tmp, &key_schedule2, DES_DECRYPT); memcpy(clr,tmp,8); DES_ecb_encrypt((const_DES_cblock *)clr, (DES_cblock *)tmp, &key_schedule, DES_ENCRYPT); bytestring_assign_data(dst,8,tmp); bytestring_free(padded_src); } else return CRYPTO_ERROR_UNKNOWN_ALGORITHM; return CRYPTO_OK; }
static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) { BLOCK_CIPHER_ecb_loop() DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), ctx->cipher_data, ctx->encrypt); return 1; }
static void ecb_test(char key[8], char in[8], char out[8]) { unsigned char k[8], indata[8], outdata[8], outdata2[8], ansdata[8]; DES_key_schedule s; memcpy(k, key, 8); memcpy(indata, in, 8); memcpy(ansdata, out, 8); DES_set_odd_parity(&k); DES_set_key_unchecked(&k, &s); DES_ecb_encrypt(&indata, &outdata, &s, 1); if (memcmp(outdata, ansdata, sizeof(ansdata)) != 0) errx(1, "des: encrypt"); DES_ecb_encrypt(&outdata, &outdata2, &s, 0); if (memcmp(indata, outdata2, sizeof(outdata2)) != 0) errx(1, "des: decrypt"); }
/* 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 void decrypt(void *p, off_t len) { DES_cblock *pblock; int num_blocks; num_blocks = (len - 3) / 8; pblock = (DES_cblock *) (p + 3); while (num_blocks--) { DES_ecb_encrypt(pblock, pblock, &schedule, DES_DECRYPT); pblock++; } num_blocks = len / 8; pblock = (DES_cblock *) p; while (num_blocks--) { DES_ecb_encrypt(pblock, pblock, &schedule, DES_DECRYPT); pblock++; } }
void des_ecb_crypt(unsigned char* input, unsigned char* output, int encrypt, unsigned char* key) { des_key_schedule sched; des_set_key((des_cblock *) key, sched); DES_ecb_encrypt((const_DES_cblock *)input, (const_DES_cblock *)output, &sched, encrypt); }
void cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH], unsigned char *src, unsigned char *dst) { DES_key_schedule sched; DES_set_key_unchecked((DES_cblock*)key, &sched); DES_ecb_encrypt((DES_cblock *)src, (DES_cblock *)dst, &sched, DES_ENCRYPT); }
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); }
GByteArray* gq_hash_lmhash(gchar const* data, gsize len) { unsigned int i; char hex[2]; char plain[15]; DES_key_schedule schedule; GByteArray *gb = NULL; DES_cblock ckey1, ckey2; DES_cblock bin1, bin2; memset(plain, 0, sizeof(plain)); for (i = 0 ; i < len && i < 14 ; i++) { plain[i] = toupper(data[i]); } lm_make_key(plain, &ckey1); DES_set_key_unchecked(&ckey1, &schedule); DES_ecb_encrypt((DES_cblock*)lmhash_key, &bin1, &schedule, DES_ENCRYPT); lm_make_key(plain + 7, &ckey2); DES_set_key_unchecked(&ckey2, &schedule); DES_ecb_encrypt((DES_cblock*)lmhash_key, &bin2, &schedule, DES_ENCRYPT); gb = g_byte_array_new(); for(i = 0 ; i < sizeof(bin1) ; i++) { hex[0] = hexdigit[bin1[i] / 16]; hex[1] = hexdigit[bin1[i] % 16]; g_byte_array_append(gb, (guchar*)hex, 2); } for(i = 0 ; i < sizeof(bin2) ; i++) { hex[0] = hexdigit[bin2[i] / 16]; hex[1] = hexdigit[bin2[i] % 16]; g_byte_array_append(gb, (guchar*)hex, 2); } return gb; }
void hitron_crypt(FILE *out, FILE *in, int enc) { size_t i, n = -1; DES_cblock buffer[BUFFER_SIZE]; DES_key_schedule schedule; DES_set_key_unchecked(&hitron_key, &schedule); while((n = fread((void *)&buffer, sizeof(DES_cblock), BUFFER_SIZE, in)) > 0) { for(i = 0; i < n; i++) { DES_ecb_encrypt(&buffer[i], &buffer[i], &schedule, enc); } fwrite((void *)&buffer, sizeof(DES_cblock), n, out); } }
void tokenchallenge(char *user, char *challenge, int size, char *card_type) { TOKENDB_Rec tr; TOKEN_CBlock cb; DES_key_schedule ks; int r, c; r = 1; /* no reduced input mode by default! */ if ((tt->modes & TOKEN_RIM) && tokendb_getrec(user, &tr) == 0 && (tr.mode & TOKEN_RIM)) { c = 0; while ((r = tokendb_lockrec(user, &tr, TOKEN_LOCKED)) == 1) { if (c++ >= 60) break; sleep(1); } tr.flags &= ~TOKEN_LOCKED; if (r == 0 && tr.rim[0]) { h2cb(tr.secret, &cb); DES_fixup_key_parity(&cb.cb); DES_key_sched(&cb.cb, &ks); DES_ecb_encrypt(&tr.rim, &cb.cb, &ks, DES_ENCRYPT); memcpy(tr.rim, cb.cb, 8); for (r = 0; r < 8; ++r) { if ((tr.rim[r] &= 0xf) > 9) tr.rim[r] -= 10; tr.rim[r] |= 0x30; } r = 0; /* reset it back */ memcpy(tokennumber.ct, tr.rim, 8); tokennumber.ct[8] = 0; tokendb_putrec(user, &tr); } } if (r != 0 || tr.rim[0] == '\0') { memset(tokennumber.ct, 0, sizeof(tokennumber.ct)); snprintf(tokennumber.ct, sizeof(tokennumber.ct), "%8.8u", arc4random()); if (r == 0) { memcpy(tr.rim, tokennumber.ct, 8); tokendb_putrec(user, &tr); } } snprintf(challenge, size, "%s Challenge \"%s\"\r\n%s Response: ", card_type, tokennumber.ct, card_type); }
static uint64_t feistel_enc(uint32_t a, uint32_t b, uint32_t m, uint8_t *key[], uint32_t round) { uint64_t L, R; uint64_t tmp, nval; uint64_t mod; uint8_t val[8]; uint8_t res[8]; int i; DES_cblock ckey; DES_key_schedule schd; L = m % a; R = (uint64_t)floor((double)m / (double)a); memset(val, 0, 8 * sizeof(uint8_t)); for(i = 0; i < round; i ++) { memcpy(val, &R, 8 * sizeof(uint8_t)); memset(&ckey, 0, sizeof(DES_cblock)); memcpy(&ckey, key[i], PERMKEYLENGTH); memset(res, 0, 8 * sizeof(char)); memset(&schd, 0, sizeof(DES_key_schedule)); DES_set_odd_parity(&ckey); DES_set_key_checked(&ckey, &schd); DES_ecb_encrypt((const_DES_cblock *)val, (DES_cblock *)res, &schd, DES_ENCRYPT); nval = *((uint64_t *)res); mod = ((i & 0x1) == 0) ? a : b; tmp = ((L % mod)+ (nval % mod)) % mod; L = R; R = tmp; memset(val, 0, 8 * sizeof(uint8_t)); } if((round & 0x1) == 1) { return a * L + R; } else { return a * R + L; } }
static int ossl_des_ecb_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) { unsigned bs = gen_ossl_block_size(c); unsigned i; ossldata *od = c->ptr; for (i = 0; i < dlen / bs; i++) DES_ecb_encrypt((DES_cblock *) (data + i * bs), (DES_cblock *) (res + i * bs), &od->u.des.key_schedule, 0); return 0; }
static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len) { if (in_len < ctx->cipher->block_size) { return 1; } in_len -= ctx->cipher->block_size; EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data; for (size_t i = 0; i <= in_len; i += ctx->cipher->block_size) { DES_ecb_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i), &dat->ks.ks, ctx->encrypt); } return 1; }
int _des_crypt(char *buf, int len, struct desparams *desp) { DES_key_schedule ks; int enc; DES_set_key_unchecked(&desp->des_key, &ks); enc = (desp->des_dir == ENCRYPT) ? DES_ENCRYPT : DES_DECRYPT; if (desp->des_mode == CBC) DES_ecb_encrypt((const_DES_cblock *)desp->UDES.UDES_buf, (DES_cblock *)desp->UDES.UDES_buf, &ks, enc); else { DES_ncbc_encrypt(desp->UDES.UDES_buf, desp->UDES.UDES_buf, len, &ks, &desp->des_ivec, enc); } return (1); }
void ofb64_encrypt(unsigned char *s, int c) { struct stinfo *stp = &fb[OFB].streams[DIR_ENCRYPT-1]; int index; index = stp->str_index; while (c-- > 0) { if (index == sizeof(DES_cblock)) { DES_cblock b; DES_ecb_encrypt(&stp->str_feed,&b, &stp->str_sched, 1); memcpy(stp->str_feed, b, sizeof(DES_cblock)); index = 0; } *s++ ^= stp->str_feed[index]; index++; } stp->str_index = index; }
void EncryptDecryptUtil::Des_Ecb_Decrypt(char* srcBytes, uint32 srcLen, char* destBytes, const char* encryptKey) { DES_key_schedule schedule; DES_set_key_unchecked((const_DES_cblock*)encryptKey, &schedule); unsigned char padChar = '\0'; uint32 alignLen = (srcLen / 8 + (srcLen % 8 ? 1 : 0)) * 8; memset(srcBytes + srcLen, padChar, 8 - srcLen % 8); uint32 count = srcLen / 8; uint32 idx = 0; for (idx = 0; idx < count; idx++) { DES_ecb_encrypt((const_DES_cblock*)(srcBytes + 8 * idx), (DES_cblock*)(destBytes + 8 * idx), &schedule, DES_DECRYPT); } memcpy(srcBytes + 8 * idx, destBytes + 8 * idx, 8 - srcLen % 8); }
NOEXPORT void crypt_DES(DES_cblock dst, const_DES_cblock src, DES_cblock hash) { DES_cblock key; DES_key_schedule sched; /* convert key from 56 to 64 bits */ key[0]=hash[0]; key[1]=((hash[0]&1)<<7)|(hash[1]>>1); key[2]=((hash[1]&3)<<6)|(hash[2]>>2); key[3]=((hash[2]&7)<<5)|(hash[3]>>3); key[4]=((hash[3]&15)<<4)|(hash[4]>>4); key[5]=((hash[4]&31)<<3)|(hash[5]>>5); key[6]=((hash[5]&63)<<2)|(hash[6]>>6); key[7]=((hash[6]&127)<<1); DES_set_odd_parity(&key); /* encrypt */ DES_set_key_unchecked(&key, &sched); DES_ecb_encrypt((const_DES_cblock *)src, (DES_cblock *)dst, &sched, DES_ENCRYPT); }
void cfb64_encrypt(unsigned char *s, int c) { struct stinfo *stp = &fb[CFB].streams[DIR_ENCRYPT-1]; int index; index = stp->str_index; while (c-- > 0) { if (index == sizeof(DES_cblock)) { DES_cblock b; DES_ecb_encrypt(&stp->str_output, &b,&stp->str_sched, 1); memcpy(stp->str_feed, b, sizeof(DES_cblock)); index = 0; } /* On encryption, we store (feed ^ data) which is cypher */ *s = stp->str_output[index] = (stp->str_feed[index] ^ *s); s++; index++; } stp->str_index = index; }
NNT_BEGIN_HEADER_C # include <openssl/des.h> # include <math.h> NNT_END_HEADER_C NNT_BEGIN_CXX void des::encrypt(char const* key, core::string const& in, core::vector<byte>& out) { DES_cblock key_block; DES_key_schedule schedule; DES_string_to_key(key, &key_block); DES_set_key_checked(&key_block, &schedule); usize sz = (usize)ceil((double)in.size() / sizeof(DES_cblock)) * sizeof(DES_cblock); out.resize(sz); core::string::const_iterator iter = in.begin(); DES_cblock* output = (DES_cblock*)core::pointer(out); DES_cblock input; while (iter != in.end()) { usize sz = in.end() - iter; if (sz >= 8) sz = 8; else memset(input, 0, sizeof(DES_cblock)); memcpy(input, &*iter, sz); DES_ecb_encrypt(&input, output, &schedule, DES_ENCRYPT); iter += sz; output += 1; } }
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; }
static void do_getticket (krb5_context context, krb5_kdc_configuration *config, struct rx_header *hdr, krb5_storage *sp, struct sockaddr_in *addr, const char *from, krb5_data *reply) { krb5_error_code ret; int kvno; char *auth_domain = NULL; krb5_data aticket; char *name = NULL; char *instance = NULL; krb5_data times; int32_t max_seq_len; hdb_entry_ex *server_entry = NULL; hdb_entry_ex *client_entry = NULL; hdb_entry_ex *krbtgt_entry = NULL; Key *kkey = NULL; Key *skey = NULL; DES_cblock key; DES_key_schedule schedule; DES_cblock session; time_t max_life; int8_t life; time_t start_time, end_time; char server_name[256]; char client_name[256]; struct _krb5_krb_auth_data ad; krb5_data_zero (&aticket); krb5_data_zero (×); memset(&ad, 0, sizeof(ad)); unparse_getticket_args (sp, &kvno, &auth_domain, &aticket, &name, &instance, ×, &max_seq_len); if (times.length < 8) { make_error_reply (hdr, KABADREQUEST, reply); goto out; } snprintf (server_name, sizeof(server_name), "%s.%s@%s", name, instance, config->v4_realm); ret = _kdc_db_fetch4 (context, config, name, instance, config->v4_realm, HDB_F_GET_SERVER, &server_entry); if (ret) { kdc_log(context, config, 0, "Server not found in database: %s: %s", server_name, krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOENT, reply); goto out; } ret = _kdc_db_fetch4 (context, config, "krbtgt", config->v4_realm, config->v4_realm, HDB_F_GET_KRBTGT, &krbtgt_entry); if (ret) { kdc_log(context, config, 0, "Server not found in database: %s.%s@%s: %s", "krbtgt", config->v4_realm, config->v4_realm, krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOENT, reply); goto out; } /* find a DES key */ ret = _kdc_get_des_key(context, krbtgt_entry, TRUE, TRUE, &kkey); if(ret){ kdc_log(context, config, 0, "no suitable DES key for krbtgt"); make_error_reply (hdr, KANOKEYS, reply); goto out; } /* find a DES key */ ret = _kdc_get_des_key(context, server_entry, TRUE, TRUE, &skey); if(ret){ kdc_log(context, config, 0, "no suitable DES key for server"); make_error_reply (hdr, KANOKEYS, reply); goto out; } /* decrypt the incoming ticket */ memcpy (&key, kkey->key.keyvalue.data, sizeof(key)); /* unpack the ticket */ { char *sname = NULL; char *sinstance = NULL; ret = _krb5_krb_decomp_ticket(context, &aticket, &kkey->key, config->v4_realm, &sname, &sinstance, &ad); if (ret) { const char *msg = krb5_get_error_message(context, ret); kdc_log(context, config, 0, "kaserver: decomp failed for %s.%s with %s %d", msg, sname, sinstance, ret); krb5_free_error_message(context, msg); make_error_reply (hdr, KABADTICKET, reply); goto out; } if (strcmp (sname, "krbtgt") != 0 || strcmp (sinstance, config->v4_realm) != 0) { kdc_log(context, config, 0, "no TGT: %s.%s for %s.%s@%s", sname, sinstance, ad.pname, ad.pinst, ad.prealm); make_error_reply (hdr, KABADTICKET, reply); free(sname); free(sinstance); goto out; } free(sname); free(sinstance); if (kdc_time > _krb5_krb_life_to_time(ad.time_sec, ad.life)) { kdc_log(context, config, 0, "TGT expired: %s.%s@%s", ad.pname, ad.pinst, ad.prealm); make_error_reply (hdr, KABADTICKET, reply); goto out; } } snprintf (client_name, sizeof(client_name), "%s.%s@%s", ad.pname, ad.pinst, ad.prealm); kdc_log(context, config, 0, "TGS-REQ (kaserver) %s from %s for %s", client_name, from, server_name); ret = _kdc_db_fetch4 (context, config, ad.pname, ad.pinst, ad.prealm, HDB_F_GET_CLIENT, &client_entry); if(ret && ret != HDB_ERR_NOENTRY) { kdc_log(context, config, 0, "Client not found in database: (krb4) %s: %s", client_name, krb5_get_err_text(context, ret)); make_error_reply (hdr, KANOENT, reply); goto out; } if (client_entry == NULL && strcmp(ad.prealm, config->v4_realm) == 0) { kdc_log(context, config, 0, "Local client not found in database: (krb4) " "%s", client_name); make_error_reply (hdr, KANOENT, reply); goto out; } ret = kdc_check_flags (context, config, client_entry, client_name, server_entry, server_name, FALSE); if (ret) { make_error_reply (hdr, KAPWEXPIRED, reply); goto out; } /* decrypt the times */ memcpy(&session, ad.session.keyvalue.data, sizeof(session)); DES_set_key_unchecked (&session, &schedule); DES_ecb_encrypt (times.data, times.data, &schedule, DES_DECRYPT); memset (&schedule, 0, sizeof(schedule)); memset (&session, 0, sizeof(session)); /* and extract them */ { krb5_storage *tsp; int32_t tmp; tsp = krb5_storage_from_mem (times.data, times.length); krb5_ret_int32 (tsp, &tmp); start_time = tmp; krb5_ret_int32 (tsp, &tmp); end_time = tmp; krb5_storage_free (tsp); } /* life */ max_life = end_time - kdc_time; /* end_time - kdc_time can sometimes be non-positive due to slight time skew between client and server. Let's make sure it is postive */ if(max_life < 1) max_life = 1; if (krbtgt_entry->entry.max_life) max_life = min(max_life, *krbtgt_entry->entry.max_life); if (server_entry->entry.max_life) max_life = min(max_life, *server_entry->entry.max_life); /* if this is a cross realm request, the client_entry will likely be NULL */ if (client_entry && client_entry->entry.max_life) max_life = min(max_life, *client_entry->entry.max_life); life = _krb5_krb_time_to_life(kdc_time, kdc_time + max_life); create_reply_ticket (context, hdr, skey, ad.pname, ad.pinst, ad.prealm, addr, life, server_entry->entry.kvno, max_seq_len, name, instance, 0, "gtkt", &ad.session, reply); out: _krb5_krb_free_auth_data(context, &ad); if (aticket.length) { memset (aticket.data, 0, aticket.length); krb5_data_free (&aticket); } if (times.length) { memset (times.data, 0, times.length); krb5_data_free (×); } if (auth_domain) free (auth_domain); if (name) free (name); if (instance) free (instance); if (krbtgt_entry) _kdc_free_ent (context, krbtgt_entry); if (server_entry) _kdc_free_ent (context, server_entry); }
int tokenuserinit(int flags, char *username, unsigned char *usecret, unsigned mode) { TOKENDB_Rec tokenrec; TOKEN_CBlock secret; TOKEN_CBlock nulls; TOKEN_CBlock checksum; TOKEN_CBlock checktxt; DES_key_schedule key_schedule; memset(&secret, 0, sizeof(secret)); /* * If no user secret passed in, create one */ if ( (flags & TOKEN_GENSECRET) ) tokenseed(&secret); else memcpy(&secret, usecret, sizeof(DES_cblock)); DES_fixup_key_parity(&secret.cb); /* * Check if the db record already exists. If there's no * force-init flag and it exists, go away. Else, * create the user's db record and put to the db. */ if (!(flags & TOKEN_FORCEINIT) && tokendb_getrec(username, &tokenrec) == 0) return (1); memset(&tokenrec, 0, sizeof(tokenrec)); strlcpy(tokenrec.uname, username, sizeof(tokenrec.uname)); cb2h(secret, tokenrec.secret); tokenrec.mode = 0; tokenrec.flags = TOKEN_ENABLED | TOKEN_USEMODES; tokenrec.mode = mode; memset(tokenrec.reserved_char1, 0, sizeof(tokenrec.reserved_char1)); memset(tokenrec.reserved_char2, 0, sizeof(tokenrec.reserved_char2)); if (tokendb_putrec(username, &tokenrec)) return (-1); /* * Check if the shared secret was generated here. If so, we * need to inform the user about it in order that it can be * programmed into the token. See tokenverify() (above) for * discussion of cipher generation. */ if (!(flags & TOKEN_GENSECRET)) { memset(&secret, 0, sizeof(secret)); return (0); } printf("Shared secret for %s\'s token: " "%03o %03o %03o %03o %03o %03o %03o %03o\n", username, secret.cb[0], secret.cb[1], secret.cb[2], secret.cb[3], secret.cb[4], secret.cb[5], secret.cb[6], secret.cb[7]); DES_key_sched(&secret.cb, &key_schedule); memset(&secret, 0, sizeof(secret)); memset(&nulls, 0, sizeof(nulls)); DES_ecb_encrypt(&nulls.cb, &checksum.cb, &key_schedule, DES_ENCRYPT); memset(&key_schedule, 0, sizeof(key_schedule)); HTONL(checksum.ul[0]); snprintf(checktxt.ct, sizeof(checktxt.ct), "%8.8x", checksum.ul[0]); printf("Hex Checksum: \"%s\"", checktxt.ct); h2d(checktxt.ct); printf("\tDecimal Checksum: \"%s\"\n", checktxt.ct); return (0); }