static int cast_test_iterations(void) { long l; int testresult = 1; CAST_KEY key, key_b; unsigned char out_a[16], out_b[16]; memcpy(out_a, in_a, sizeof(in_a)); memcpy(out_b, in_b, sizeof(in_b)); for (l = 0; l < 1000000L; l++) { CAST_set_key(&key_b, 16, out_b); CAST_ecb_encrypt(&(out_a[0]), &(out_a[0]), &key_b, CAST_ENCRYPT); CAST_ecb_encrypt(&(out_a[8]), &(out_a[8]), &key_b, CAST_ENCRYPT); CAST_set_key(&key, 16, out_a); CAST_ecb_encrypt(&(out_b[0]), &(out_b[0]), &key, CAST_ENCRYPT); CAST_ecb_encrypt(&(out_b[8]), &(out_b[8]), &key, CAST_ENCRYPT); } if (!TEST_mem_eq(out_a, sizeof(c_a), c_a, sizeof(c_a)) || !TEST_mem_eq(out_b, sizeof(c_b), c_b, sizeof(c_b))) testresult = 0; return testresult; }
static void cast5_init(ops_crypt_t *crypt) { if (crypt->encrypt_key) free(crypt->encrypt_key); crypt->encrypt_key=malloc(sizeof(CAST_KEY)); CAST_set_key(crypt->encrypt_key,crypt->keysize,crypt->key); crypt->decrypt_key=malloc(sizeof(CAST_KEY)); CAST_set_key(crypt->decrypt_key,crypt->keysize,crypt->key); }
static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); return 1; }
static int cast5_init(pgp_crypt_t *crypt) { if (crypt->encrypt_key) { free(crypt->encrypt_key); } if ((crypt->encrypt_key = calloc(1, sizeof(CAST_KEY))) == NULL) { (void) fprintf(stderr, "cast5_init: alloc failure\n"); return 0; } CAST_set_key(crypt->encrypt_key, (int)crypt->keysize, crypt->key); if ((crypt->decrypt_key = calloc(1, sizeof(CAST_KEY))) == NULL) { (void) fprintf(stderr, "cast5_init: alloc failure\n"); return 0; } CAST_set_key(crypt->decrypt_key, (int)crypt->keysize, crypt->key); return 1; }
void cipher_set_key_iv(CipherContext * context, int cipher, const unsigned char *key, int keylen, const unsigned char *iv, int ivlen) { /* Set cipher type. */ context->type = cipher; /* Initialize the initialization vector. */ switch (cipher) { case SSH_CIPHER_NONE: break; case SSH_CIPHER_3DES: case SSH_CIPHER_BLOWFISH: fatal("cipher_set_key_iv: illegal cipher: %s", cipher_name(cipher)); break; case SSH_CIPHER_3DES_CBC: if (keylen < 24) error("Key length %d is insufficient for 3des-cbc.", keylen); des_set_key((void *) key, context->u.des3.key1); des_set_key((void *) (key+8), context->u.des3.key2); des_set_key((void *) (key+16), context->u.des3.key3); if (ivlen < 8) error("IV length %d is insufficient for 3des-cbc.", ivlen); memcpy(context->u.des3.iv3, (char *)iv, 8); break; case SSH_CIPHER_BLOWFISH_CBC: if (keylen < 16) error("Key length %d is insufficient for blowfish.", keylen); if (ivlen < 8) error("IV length %d is insufficient for blowfish.", ivlen); BF_set_key(&context->u.bf.key, keylen, (unsigned char *)key); memcpy(context->u.bf.iv, (char *)iv, 8); break; case SSH_CIPHER_ARCFOUR: if (keylen < 16) error("Key length %d is insufficient for arcfour.", keylen); RC4_set_key(&context->u.rc4, keylen, (unsigned char *)key); break; case SSH_CIPHER_CAST128_CBC: if (keylen < 16) error("Key length %d is insufficient for cast128.", keylen); if (ivlen < 8) error("IV length %d is insufficient for cast128.", ivlen); CAST_set_key(&context->u.cast.key, keylen, (unsigned char *) key); memcpy(context->u.cast.iv, (char *)iv, 8); break; default: fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher)); } }
static void run_crypto_cast128(uint8_t *output, const uint8_t *input, unsigned size) { CAST_KEY cast; unsigned i; CAST_set_key(&cast, 16, hardcoded_key); for (i = 0; i < size; i += 8) CAST_ecb_encrypt(input + i, output + i, &cast, 1); }
static int ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv) { ossldata *od = c->ptr; unsigned bs = gen_ossl_block_size(c); CAST_set_key(&od->u.cast_key, klen, key); if (iv) memcpy(od->iv, iv, bs); else memset(od->iv, 0, bs); return 0; }
static int ssh_cast5_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { struct ssh_cast5_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) { CAST_set_key(&c->cast5_ctx, EVP_CIPHER_CTX_key_length(ctx), key); } if (iv != NULL) memcpy(c->cast5_counter, iv, CAST_BLOCK); return (1); }
static int cast_test_vector(int z) { int testresult = 1; CAST_KEY key; unsigned char out[80]; CAST_set_key(&key, k_len[z], k); CAST_ecb_encrypt(in, out, &key, CAST_ENCRYPT); if (!TEST_mem_eq(out, sizeof(c[z]), c[z], sizeof(c[z]))) { TEST_info("CAST_ENCRYPT iteration %d failed (len=%d)", z, k_len[z]); testresult = 0; } CAST_ecb_encrypt(out, out, &key, CAST_DECRYPT); if (!TEST_mem_eq(out, sizeof(in), in, sizeof(in))) { TEST_info("CAST_DECRYPT iteration %d failed (len=%d)", z, k_len[z]); testresult = 0; } return testresult; }
int main(int argc, char *argv[]) { #ifdef FULL_TEST long l; CAST_KEY key_b; #endif int i,z,err=0; CAST_KEY key; for (z=0; z<3; z++) { CAST_set_key(&key,k_len[z],k); CAST_ecb_encrypt(in,out,&key,CAST_ENCRYPT); if (memcmp(out,&(c[z][0]),8) != 0) { printf("ecb cast error encrypting for keysize %d\n",k_len[z]*8); printf("got :"); for (i=0; i<8; i++) printf("%02X ",out[i]); printf("\n"); printf("expected:"); for (i=0; i<8; i++) printf("%02X ",c[z][i]); err=20; printf("\n"); } CAST_ecb_encrypt(out,out,&key,CAST_DECRYPT); if (memcmp(out,in,8) != 0) { printf("ecb cast error decrypting for keysize %d\n",k_len[z]*8); printf("got :"); for (i=0; i<8; i++) printf("%02X ",out[i]); printf("\n"); printf("expected:"); for (i=0; i<8; i++) printf("%02X ",in[i]); printf("\n"); err=3; } } if (err == 0) printf("ecb cast5 ok\n"); #ifdef FULL_TEST { unsigned char out_a[16],out_b[16]; static char *hex="0123456789ABCDEF"; printf("This test will take some time...."); fflush(stdout); memcpy(out_a,in_a,sizeof(in_a)); memcpy(out_b,in_b,sizeof(in_b)); i=1; for (l=0; l<1000000L; l++) { CAST_set_key(&key_b,16,out_b); CAST_ecb_encrypt(&(out_a[0]),&(out_a[0]),&key_b,CAST_ENCRYPT); CAST_ecb_encrypt(&(out_a[8]),&(out_a[8]),&key_b,CAST_ENCRYPT); CAST_set_key(&key,16,out_a); CAST_ecb_encrypt(&(out_b[0]),&(out_b[0]),&key,CAST_ENCRYPT); CAST_ecb_encrypt(&(out_b[8]),&(out_b[8]),&key,CAST_ENCRYPT); if ((l & 0xffff) == 0xffff) { printf("%c",hex[i&0x0f]); fflush(stdout); i++; } } if ( (memcmp(out_a,c_a,sizeof(c_a)) != 0) || (memcmp(out_b,c_b,sizeof(c_b)) != 0)) { printf("\n"); printf("Error\n"); printf("A out ="); for (i=0; i<16; i++) printf("%02X ",out_a[i]); printf("\nactual="); for (i=0; i<16; i++) printf("%02X ",c_a[i]); printf("\n"); printf("B out ="); for (i=0; i<16; i++) printf("%02X ",out_b[i]); printf("\nactual="); for (i=0; i<16; i++) printf("%02X ",c_b[i]); printf("\n"); } else printf(" ok\n"); } #endif exit(err); }
int main (int argc, char **argv) { long count; static unsigned char buf[BUFSIZE]; static unsigned char key[] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, }; CAST_KEY sch; double a, b, c, d; #ifndef SIGALRM long ca, cb, cc; #endif #ifndef TIMES printf ("To get the most accurate results, try to run this\n"); printf ("program when this computer is idle.\n"); #endif #ifndef SIGALRM printf ("First we calculate the approximate speed ...\n"); CAST_set_key (&sch, 16, key); count = 10; do { long i; CAST_LONG data[2]; count *= 2; Time_F (START); for (i = count; i; i--) CAST_encrypt (data, &sch); d = Time_F (STOP); } while (d < 3.0); ca = count / 512; cb = count; cc = count * 8 / BUFSIZE + 1; printf ("Doing CAST_set_key %ld times\n", ca); #define COND(d) (count != (d)) #define COUNT(d) (d) #else #define COND(c) (run) #define COUNT(d) (count) signal (SIGALRM, sig_done); printf ("Doing CAST_set_key for 10 seconds\n"); alarm (10); #endif Time_F (START); for (count = 0, run = 1; COND (ca); count += 4) { CAST_set_key (&sch, 16, key); CAST_set_key (&sch, 16, key); CAST_set_key (&sch, 16, key); CAST_set_key (&sch, 16, key); } d = Time_F (STOP); printf ("%ld cast set_key's in %.2f seconds\n", count, d); a = ((double) COUNT (ca)) / d; #ifdef SIGALRM printf ("Doing CAST_encrypt's for 10 seconds\n"); alarm (10); #else printf ("Doing CAST_encrypt %ld times\n", cb); #endif Time_F (START); for (count = 0, run = 1; COND (cb); count += 4) { CAST_LONG data[2]; CAST_encrypt (data, &sch); CAST_encrypt (data, &sch); CAST_encrypt (data, &sch); CAST_encrypt (data, &sch); } d = Time_F (STOP); printf ("%ld CAST_encrypt's in %.2f second\n", count, d); b = ((double) COUNT (cb) * 8) / d; #ifdef SIGALRM printf ("Doing CAST_cbc_encrypt on %ld byte blocks for 10 seconds\n", BUFSIZE); alarm (10); #else printf ("Doing CAST_cbc_encrypt %ld times on %ld byte blocks\n", cc, BUFSIZE); #endif Time_F (START); for (count = 0, run = 1; COND (cc); count++) CAST_cbc_encrypt (buf, buf, BUFSIZE, &sch, &(key[0]), CAST_ENCRYPT); d = Time_F (STOP); printf ("%ld CAST_cbc_encrypt's of %ld byte blocks in %.2f second\n", count, BUFSIZE, d); c = ((double) COUNT (cc) * BUFSIZE) / d; printf ("CAST set_key per sec = %12.2f (%9.3fuS)\n", a, 1.0e6 / a); printf ("CAST raw ecb bytes per sec = %12.2f (%9.3fuS)\n", b, 8.0e6 / b); printf ("CAST cbc bytes per sec = %12.2f (%9.3fuS)\n", c, 8.0e6 / c); exit (0); #if defined(LINT) || defined(OPENSSL_SYS_MSDOS) return (0); #endif }
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; }
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; }
int main(int argc, char **argv) { long count; static unsigned char buf[BUFSIZE]; static char key[16]={ 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0, 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; CAST_KEY sch; double d,tm[16],max=0; int rank[16]; char *str[16]; int max_idx=0,i,num=0,j; #ifndef SIGALARM long ca,cb,cc,cd,ce; #endif for (i=0; i<12; i++) { tm[i]=0.0; rank[i]=0; } #ifndef TIMES fprintf(stderr,"To get the most accurate results, try to run this\n"); fprintf(stderr,"program when this computer is idle.\n"); #endif CAST_set_key(&sch,16,key); #ifndef SIGALRM fprintf(stderr,"First we calculate the approximate speed ...\n"); count=10; do { long i; CAST_LONG data[2]; count*=2; Time_F(START); for (i=count; i; i--) CAST_encrypt(data,&sch); d=Time_F(STOP); } while (d < 3.0); ca=count; cb=count*3; cc=count*3*8/BUFSIZE+1; cd=count*8/BUFSIZE+1; ce=count/20+1; #define COND(d) (count != (d)) #define COUNT(d) (d) #else #define COND(c) (run) #define COUNT(d) (count) signal(SIGALRM,sig_done); alarm(10); #endif time_it(CAST_encrypt_normal, "CAST_encrypt_normal ", 0); time_it(CAST_encrypt_ptr, "CAST_encrypt_ptr ", 1); time_it(CAST_encrypt_ptr2, "CAST_encrypt_ptr2 ", 2); num+=3; str[0]="<nothing>"; print_it("CAST_encrypt_normal ",0); max=tm[0]; max_idx=0; str[1]="ptr "; print_it("CAST_encrypt_ptr ",1); if (max < tm[1]) { max=tm[1]; max_idx=1; } str[2]="ptr2 "; print_it("CAST_encrypt_ptr2 ",2); if (max < tm[2]) { max=tm[2]; max_idx=2; } printf("options CAST ecb/s\n"); printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]); d=tm[max_idx]; tm[max_idx]= -2.0; max= -1.0; for (;;) { for (i=0; i<3; i++) { if (max < tm[i]) { max=tm[i]; j=i; } } if (max < 0.0) break; printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0); tm[j]= -2.0; max= -1.0; } switch (max_idx) { case 0: printf("-DCAST_DEFAULT_OPTIONS\n"); break; case 1: printf("-DCAST_PTR\n"); break; case 2: printf("-DCAST_PTR2\n"); break; } exit(0); #if defined(LINT) || defined(OPENSSL_SYS_MSDOS) return(0); #endif }
int main(void) { int i; CAST_KEY key; BIO* bio_out; unsigned char key_data[CAST_KEY_LENGTH] = { 0x6d, 0x01, 0x81, 0x09, 0xbb, 0x73, 0xf4, 0xed, 0xd2, 0xbf, 0x74, 0x10, 0x45, 0x95, 0xe6, 0x16, }; unsigned char iv[CAST_BLOCK]; unsigned char const iv_data[CAST_BLOCK] = { 0x73, 0xa1, 0x2a, 0x82, 0x62, 0x25, 0xa1, 0x13 }; char* data = "The worthwhile problems are the ones you can" "really solve or help solve, the ones you can" "really contribute something to. No " "problem is too small or too trivial if we " "can really do something about it." "- Richard Feynman"; int length = (int) strlen(data); /* Initialize how far we've gone through the IV */ int num = 0; /* Allocate some space for the ciphertext and plaintext */ char* ciphertext = (char*) malloc(sizeof(char) * length); char* plaintext = (char*) malloc(sizeof(char) * length); /* Copy the IV data to the IV array */ memcpy(iv, iv_data, CAST_BLOCK); /* Set the encrypt key structure using the predefined key */ CAST_set_key(&key, CAST_KEY_LENGTH * 8, key_data); /* Carry out the encryption */ CAST_ofb64_encrypt(data, ciphertext, length, &key, iv, &num); /* Setup output */ bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); BIO_printf(bio_out, "Original plaintext: %s\n\n", data); BIO_printf(bio_out, "Ciphertext: "); /* Print out the ciphertext */ for (i = 0; i < length; i++) BIO_printf(bio_out, "%02x", ((unsigned char*)ciphertext)[i]); BIO_printf(bio_out, "\n\n"); /* Start the decryption process */ /* First, copy the original IV data back to the IV array - as it was overwritten * during the encryption process */ memcpy(iv, iv_data, CAST_BLOCK); /* Reset how far we've gone through the IV */ num = 0; /* Note: we don't need to set the decrypt key (as in other samples) */ /* because encryption and decryption processes are the same for OFB. */ /* Carry out the decryption */ CAST_ofb64_encrypt(ciphertext, plaintext, length, &key, iv, &num); BIO_printf(bio_out, "Recovered plaintext: "); /* print out the plaintext */ for (i = 0; i < length; i++) BIO_printf(bio_out, "%c", ((unsigned char*)plaintext)[i]); BIO_printf(bio_out, "\n\n"); BIO_free(bio_out); free(ciphertext); free(plaintext); return 0; }
enum cryptoerr cast_init(struct keystate *ks, u_int8_t *key, u_int16_t len) { CAST_set_key(&ks->ks_cast, len, key); return EOKAY; }
// Checks if the given password is valid bool Tester::check(const Memblock &mblock) { const String2Key &s2k = m_key.string2Key(); int32_t tmp = 0; // Generate key from password s2k.generateKey(mblock, m_keydata, m_keySize); // 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. #if 1 memcpy(m_ivec, s2k.ivec(), m_blockSize); switch (m_cipher) { case CryptUtils::CIPHER_CAST5: { CAST_KEY ck; CAST_set_key(&ck, m_keySize, m_keydata); CAST_cfb64_encrypt(m_in, m_out, CAST_BLOCK, &ck, m_ivec, &tmp, CAST_DECRYPT); } break; case CryptUtils::CIPHER_BLOWFISH: { BF_KEY ck; BF_set_key(&ck, m_keySize, m_keydata); BF_cfb64_encrypt(m_in, m_out, BF_BLOCK, &ck, m_ivec, &tmp, BF_DECRYPT); } break; case CryptUtils::CIPHER_AES128: case CryptUtils::CIPHER_AES192: case CryptUtils::CIPHER_AES256: { AES_KEY ck; AES_set_encrypt_key(m_keydata, m_keySize * 8, &ck); AES_cfb128_encrypt(m_in, m_out, AES_BLOCK_SIZE, &ck, m_ivec, &tmp, AES_DECRYPT); } break; default: break; } uint32_t num_bits = ((m_out[0] << 8) | m_out[1]); if (num_bits < MIN_BN_BITS || num_bits > m_bits) { return false; } #endif // Decrypt all data memcpy(m_ivec, s2k.ivec(), m_blockSize); tmp = 0; switch (m_cipher) { case CryptUtils::CIPHER_CAST5: { CAST_KEY ck; CAST_set_key(&ck, m_keySize, m_keydata); CAST_cfb64_encrypt(m_in, m_out, m_datalen, &ck, m_ivec, &tmp, CAST_DECRYPT); } break; case CryptUtils::CIPHER_BLOWFISH: { BF_KEY ck; BF_set_key(&ck, m_keySize, m_keydata); BF_cfb64_encrypt(m_in, m_out, m_datalen, &ck, m_ivec, &tmp, BF_DECRYPT); } break; case CryptUtils::CIPHER_AES128: case CryptUtils::CIPHER_AES192: case CryptUtils::CIPHER_AES256: { AES_KEY ck; AES_set_encrypt_key(m_keydata, m_keySize * 8, &ck); AES_cfb128_encrypt(m_in, m_out, m_datalen, &ck, m_ivec, &tmp, AES_DECRYPT); } break; default: break; } // Verify bool checksumOk = false; switch (s2k.usage()) { case 254: { uint8_t checksum[SHA_DIGEST_LENGTH]; pgpry_SHA_CTX ctx; pgpry_SHA1_Init(&ctx); pgpry_SHA1_Update(&ctx, m_out, m_datalen - SHA_DIGEST_LENGTH); pgpry_SHA1_Final(checksum, &ctx); if (memcmp(checksum, m_out + m_datalen - SHA_DIGEST_LENGTH, SHA_DIGEST_LENGTH) == 0) { checksumOk = true; } } break; case 0: case 255: { uint16_t sum = 0; for (uint32_t i = 0; i < m_datalen - 2; i++) { sum += m_out[i]; } if (sum == ((m_out[m_datalen - 2] << 8) | m_out[m_datalen - 1])) { checksumOk = true; } } break; default: break; } // If the checksum is ok, try to parse the first MPI of the private key if (checksumOk) { BIGNUM *b = NULL; uint32_t blen = (num_bits + 7) / 8; if (blen < m_datalen && ((b = BN_bin2bn(m_out + 2, blen, NULL)) != NULL)) { BN_free(b); return true; } } return false; }