コード例 #1
0
int FIPS_selftest_des()
    {
    int n;

    /* Encrypt/decrypt with DES and compare to known answers */
    for(n=0 ; n < 2 ; ++n)
	{
	DES_key_schedule key;
	DES_cblock buf;

	DES_set_key(&tests[n].key,&key);
	DES_ecb_encrypt(&tests[n].plaintext,&buf,&key,1);
	if(memcmp(buf,tests[n].ciphertext,sizeof buf))
	    {
	    FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
	    return 0;
	    }
	DES_ecb_encrypt(&tests[n].ciphertext,&buf,&key,0);
	if(memcmp(buf,tests[n].plaintext,sizeof buf))
	    {
	    FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
	    return 0;
	    }
	}

    /* Encrypt/decrypt with 2-key 3DES and compare to known answers */
    for(n=0 ; n < 2 ; ++n)
	{
	DES_key_schedule key1, key2;
	unsigned char buf[8];

	DES_set_key(&tests2[n].key1,&key1);
	DES_set_key(&tests2[n].key2,&key2);
	DES_ecb2_encrypt(tests2[n].plaintext,buf,&key1,&key2,1);
	if(memcmp(buf,tests2[n].ciphertext,sizeof buf))
	    {
	    FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
	    return 0;
	    }
	DES_ecb2_encrypt(tests2[n].ciphertext,buf,&key1,&key2,0);
	if(memcmp(buf,tests2[n].plaintext,sizeof buf))
	    {
	    FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
	    return 0;
	    }
	}

    /* Encrypt/decrypt with 3DES and compare to known answers */
    for(n=0 ; n < 2 ; ++n)
	{
	DES_key_schedule key1, key2, key3;
	unsigned char buf[8];

	DES_set_key(&tests3[n].key1,&key1);
	DES_set_key(&tests3[n].key2,&key2);
	DES_set_key(&tests3[n].key3,&key3);
	DES_ecb3_encrypt(tests3[n].plaintext,buf,&key1,&key2,&key3,1);
	if(memcmp(buf,tests3[n].ciphertext,sizeof buf))
	    {
	    FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
	    return 0;
	    }
	DES_ecb3_encrypt(tests3[n].ciphertext,buf,&key1,&key2,&key3,0);
	if(memcmp(buf,tests3[n].plaintext,sizeof buf))
	    {
	    FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
	    return 0;
	    }
	}

    return 1;
    }
コード例 #2
0
ファイル: cardos-tool.c プロジェクト: securez/opendnie
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;
}
コード例 #3
0
static crypto_error_t crypto_cipher(bytestring_t *dst,
                                    const bytestring_t *ctx,
                                    const bytestring_t *src,
                                    const bytestring_t *iv,
                                    int enc)
{
    unsigned u;
    unsigned char alg;
    DES_key_schedule key_schedule;
    DES_key_schedule key_schedule2;

    if (bytestring_get_element(&alg,ctx,0)!=BYTESTRING_OK)
        return CRYPTO_ERROR_UNKNOWN;

    if ((bytestring_get_size(src)&0x7)!=0)
        return CRYPTO_ERROR_BAD_CLEARTEXT_LENGTH;

    switch (alg)
    {
        case CRYPTO_ALG_DES_ECB:
            bytestring_resize(dst,bytestring_get_size(src));

            memcpy(&key_schedule,ctx->data+KS_HEADER_SIZE,DES_KS_SIZE);

            for (u=0; u<bytestring_get_size(src)/8; u++)
                DES_ecb_encrypt((const_DES_cblock *)(src->data+u*8),
                                (DES_cblock *)(dst->data+u*8),
                                &key_schedule,
                                enc);
            break;
        case CRYPTO_ALG_DES_CBC:
            if (iv==NULL || bytestring_get_size(iv)!=8)
                return CRYPTO_ERROR_BAD_IV_LENGTH;

            bytestring_resize(dst,bytestring_get_size(src));

            memcpy(&key_schedule,ctx->data+KS_HEADER_SIZE,DES_KS_SIZE);
            
            DES_ncbc_encrypt(src->data,
                             dst->data,
                             bytestring_get_size(src),
                             &key_schedule,
                             (DES_cblock *)(iv->data),
                             enc);
            break;
        case CRYPTO_ALG_DES2_EDE_ECB:
            bytestring_resize(dst,bytestring_get_size(src));

            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(src)/8; u++)
                DES_ecb2_encrypt((const_DES_cblock *)(src->data+u*8),
                                 (DES_cblock *)(dst->data+u*8),
                                 &key_schedule,
                                 &key_schedule2,
                                 enc);
            break;
        case CRYPTO_ALG_DES2_EDE_CBC:
            if (iv==NULL || bytestring_get_size(iv)!=8)
                return CRYPTO_ERROR_BAD_IV_LENGTH;

            bytestring_resize(dst,bytestring_get_size(src));


            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);

            DES_ede2_cbc_encrypt(src->data,
                                 dst->data,
                                 bytestring_get_size(src),
                                 &key_schedule,
                                 &key_schedule2,
                                 (DES_cblock *)(iv->data),
                                 enc);
            break;
        default:
            return CRYPTO_ERROR_UNKNOWN_ALGORITHM;
    }
    return CRYPTO_OK;
}