Ejemplo n.º 1
0
ATF_TC_BODY(ede_cbc, tc)
{
	int i, j;
	des_cblock iv3;
	des_key_schedule ks, ks2, ks3;
	unsigned char cbc_in[40], cbc_out[40];

	if ((j = des_set_key_checked(&cbc_key, ks)) != 0)
		atf_tc_fail_nonfatal("Key error %d\n", j);
	if ((j = des_set_key_checked(&cbc2_key, ks2)) != 0)
		atf_tc_fail_nonfatal("Key error %d\n", j);
	if ((j = des_set_key_checked(&cbc3_key, ks3)) != 0)
		atf_tc_fail_nonfatal("Key error %d\n", j);
	memset(cbc_out, 0, 40);
	memset(cbc_in, 0, 40);
	i = strlen((char *) cbc_data) + 1;
	/* i=((i+7)/8)*8; */
	memcpy(iv3, cbc_iv, sizeof(cbc_iv));

	des_ede3_cbc_encrypt(cbc_data, cbc_out, 16L, ks, ks2, ks3, &iv3,
			     DES_ENCRYPT);
	des_ede3_cbc_encrypt(&(cbc_data[16]), &(cbc_out[16]), i - 16, ks, ks2,
			     ks3, &iv3, DES_ENCRYPT);
	if (memcmp(cbc_out, cbc3_ok, (unsigned int)
		   (strlen((char *) cbc_data) + 1 + 7) / 8 * 8) != 0)
		atf_tc_fail_nonfatal("des_ede3_cbc_encrypt encrypt error\n");
	memcpy(iv3, cbc_iv, sizeof(cbc_iv));
	des_ede3_cbc_encrypt(cbc_out, cbc_in, i, ks, ks2, ks3, &iv3,
			     DES_DECRYPT);
	if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0)
		atf_tc_fail_nonfatal("des_ede3_cbc_encrypt decrypt error\n");
}
Ejemplo n.º 2
0
CK_RV
sw_des3_cbc(CK_BYTE * in_data,
	    CK_ULONG in_data_len,
	    CK_BYTE *out_data,
	    CK_ULONG *out_data_len,
	    CK_BYTE *init_v,
	    CK_BYTE  *key_value,
	    CK_BYTE  encrypt)
{
	des_key_schedule des_key1;
	des_key_schedule des_key2;
	des_key_schedule des_key3;

	const_des_cblock key_SSL1, key_SSL2, key_SSL3;
	des_cblock ivec;

	// the des decrypt will only fail if the data length is not evenly divisible
	// by 8
	if (in_data_len % 8) {
		TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
		return CKR_DATA_LEN_RANGE;
	}

	// The key as passed in is a 24 byte string containing 3 keys
	// pick it apart and create the key schedules
	memcpy(&key_SSL1, key_value, (size_t)8);
	memcpy(&key_SSL2, key_value+8, (size_t)8);
	memcpy(&key_SSL3, key_value+16, (size_t)8);
	des_set_key_unchecked(&key_SSL1, des_key1);
	des_set_key_unchecked(&key_SSL2, des_key2);
	des_set_key_unchecked(&key_SSL3, des_key3);

	memcpy(ivec, init_v, sizeof(ivec));

	// Encrypt or decrypt the data
	if (encrypt) {
		des_ede3_cbc_encrypt(in_data,
				out_data,
				in_data_len,
				des_key1,
				des_key2,
				des_key3,
				&ivec,
				DES_ENCRYPT);
		*out_data_len = in_data_len;
	} else {
		des_ede3_cbc_encrypt(in_data,
				out_data,
				in_data_len,
				des_key1,
				des_key2,
				des_key3,
				&ivec,
				DES_DECRYPT);

		*out_data_len = in_data_len;
	}

	return CKR_OK;
}
/* encrypt or decrypt part of an IKE message using 3DES
 * See RFC 2409 "IKE" Appendix B
 */
static void
do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
{
    des_key_schedule ks[3];

    passert (!key_size || (key_size==(DES_CBC_BLOCK_SIZE * 3)))
    (void) des_set_key((des_cblock *)key + 0, ks[0]);
    (void) des_set_key((des_cblock *)key + 1, ks[1]);
    (void) des_set_key((des_cblock *)key + 2, ks[2]);

#if 0
crypto_display_hex ((des_cblock *)key + 0 , DES_CBC_BLOCK_SIZE,  "Key1 :");
crypto_display_hex ((des_cblock *)key + 1 , DES_CBC_BLOCK_SIZE,  "Key2 :");
crypto_display_hex ((des_cblock *)key + 2 , DES_CBC_BLOCK_SIZE,  "Key3 :");
crypto_display_hex (iv , DES_CBC_BLOCK_SIZE,  "User IV:");

	crypto_ipsec( buf, buf_len ,(des_cblock *)key + 0 ,(des_cblock *)key + 1 , (des_cblock *)key + 2 , DES_CBC_BLOCK_SIZE ,iv , enc , OAKLEY_3DES_CBC);
sleep(1);
#endif
#if 0
    des_ede3_cbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
	ks[0], ks[1], ks[2],
	(des_cblock *)iv, enc);
#endif

    des_ede3_cbc_hwencrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
	(des_cblock *)key + 0, (des_cblock *)key + 1, (des_cblock *)key + 2,
	(des_cblock *)iv, enc);

}
Ejemplo n.º 4
0
static int _3des_cbc_encrypt(struct ipsec_alg_enc *alg,
			     __u8 * key_e,
			     __u8 * in,
			     int ilen, __u8 * iv,
			     int encrypt)
{
	TripleDES_context *ctx=(TripleDES_context*)key_e;
	des_cblock miv;

	memcpy(&miv, iv, sizeof(miv));

	if (debug_3des > 0)
		printk(KERN_DEBUG "klips_debug:_3des_cbc_encrypt:"
				"key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
				key_e, in, ilen, iv, encrypt);

	des_ede3_cbc_encrypt((des_cblock *)in,
			     (des_cblock *)in,
			     ilen,
			     ctx->s1,
			     ctx->s2,
			     ctx->s3,
			     &miv, encrypt);
	return 1;
}
Ejemplo n.º 5
0
static void
c3des_cbc_dec_int(void *privdata, void *dst, void *src, int len)
{
    struct	c3des_encdata *ce = (void *)privdata;

    des_ede3_cbc_encrypt(src, dst, len, *ce->ce_key1, *ce->ce_key2,
                         *ce->ce_key3, (des_cblock *)ce->ce_iv, 0);
    memcpy(ce->ce_iv, (u_int8_t *)src + (len - 8), 8);
}
Ejemplo n.º 6
0
void
cipher_decrypt(CipherContext *context, unsigned char *dest,
	       const unsigned char *src, unsigned int len)
{
	if ((len & 7) != 0)
		fatal("cipher_decrypt: bad ciphertext length %d", len);

	switch (context->type) {
	case SSH_CIPHER_NONE:
		memcpy(dest, src, len);
		break;

	case SSH_CIPHER_3DES:
		SSH_3CBC_DECRYPT(context->u.des3.key1,
				 context->u.des3.key2, &context->u.des3.iv2,
				 context->u.des3.key3, &context->u.des3.iv3,
				 dest, (unsigned char *) src, len);
		break;

	case SSH_CIPHER_BLOWFISH:
		swap_bytes(src, dest, len);
		BF_cbc_encrypt((void *) dest, dest, len,
			       &context->u.bf.key, context->u.bf.iv,
			       BF_DECRYPT);
		swap_bytes(dest, dest, len);
		break;

	case SSH_CIPHER_BLOWFISH_CBC:
		BF_cbc_encrypt((void *) src, dest, len,
			       &context->u.bf.key, context->u.bf.iv,
			       BF_DECRYPT);
		break;

	case SSH_CIPHER_3DES_CBC:
		des_ede3_cbc_encrypt(src, dest, len,
		    context->u.des3.key1, context->u.des3.key2,
		    context->u.des3.key3, &context->u.des3.iv3, DES_DECRYPT);
		break;

	case SSH_CIPHER_ARCFOUR:
		RC4(&context->u.rc4, len, (unsigned char *)src, dest);
		break;

	case SSH_CIPHER_CAST128_CBC:
		CAST_cbc_encrypt(src, dest, len,
		    &context->u.cast.key, context->u.cast.iv, CAST_DECRYPT);
		break;

	default:
		fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type));
	}
}
Ejemplo n.º 7
0
/* encrypt or decrypt part of an IKE message using 3DES
 * See draft-ietf-ipsec-isakmp-oakley-07.txt Appendix B
 */
static void
do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
{
    des_key_schedule ks[3];

    passert (!key_size || (key_size==(DES_CBC_BLOCK_SIZE * 3)))
    (void) des_set_key((des_cblock *)key + 0, ks[0]);
    (void) des_set_key((des_cblock *)key + 1, ks[1]);
    (void) des_set_key((des_cblock *)key + 2, ks[2]);

    des_ede3_cbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
	ks[0], ks[1], ks[2],
	(des_cblock *)iv, enc);
}
Ejemplo n.º 8
0
char *
des3_encode(char *id, int key)
{
	unsigned char buf[24], out[24];
	static char result[65];
	des_cblock this_iv;
	memcpy(&this_iv, &iv, sizeof (iv));
	memcpy(buf, &now_t, 4);
	memcpy(buf + 4, id, IDLEN);
	memcpy(buf + 16, magic[key], 8);
	des_ede3_cbc_encrypt(buf, out, 24, ks[key][0], ks[key][1],
			     ks[key][2], &iv, 1);
	hex_encode(this_iv, 8, result);
	hex_encode(out, 24, result + 16);
	return result;
}
Ejemplo n.º 9
0
char *
des3_decode(char *buf, int key)
{
	des_cblock this_iv;
	char tmp[24], out[16];
	static char id[IDLEN + 1];
	id[0] = 0;
	if (strlen(buf) != 64)
		return id;
	strsncpy(tmp, buf, 17);
	hex_decode(tmp, this_iv);
	hex_decode(buf + 16, tmp);
	des_ede3_cbc_encrypt(tmp, out, 24, ks[key][0], ks[key][1],
			     ks[key][2], &this_iv, 0);
	if (memcmp(out + 16, magic[key], 8))
		return id;
	if (now_t < *((time_t *) out) || now_t > *((time_t *) out) + 86400)
		return id;
	strsncpy(id, out + 4, IDLEN + 1);
	return id;
}
Ejemplo n.º 10
0
int main(int argc, char *argv[])
	{
	int i,j,err=0;
	des_cblock in,out,outin,iv3,iv2;
	des_key_schedule ks,ks2,ks3;
	unsigned char cbc_in[40];
	unsigned char cbc_out[40];
	DES_LONG cs;
	unsigned char cret[8];
#ifdef _CRAY
        struct {
            int a:32;
            int b:32;
        } lqret[2];
#else
        DES_LONG lqret[4];
#endif
	int num;
	char *str;

#ifndef NO_DESCBCM
	printf("Doing cbcm\n");
	if ((j=des_set_key_checked(&cbc_key,ks)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	if ((j=des_set_key_checked(&cbc2_key,ks2)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	if ((j=des_set_key_checked(&cbc3_key,ks3)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	memset(cbc_out,0,40);
	memset(cbc_in,0,40);
	i=strlen((char *)cbc_data)+1;
	/* i=((i+7)/8)*8; */
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	memset(iv2,'\0',sizeof iv2);

	des_ede3_cbcm_encrypt(cbc_data,cbc_out,16L,ks,ks2,ks3,&iv3,&iv2,
			      DES_ENCRYPT);
	des_ede3_cbcm_encrypt(&cbc_data[16],&cbc_out[16],i-16,ks,ks2,ks3,
			      &iv3,&iv2,DES_ENCRYPT);
	/*	if (memcmp(cbc_out,cbc3_ok,
		(unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
		{
		printf("des_ede3_cbc_encrypt encrypt error\n");
		err=1;
		}
	*/
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	memset(iv2,'\0',sizeof iv2);
	des_ede3_cbcm_encrypt(cbc_out,cbc_in,i,ks,ks2,ks3,&iv3,&iv2,DES_DECRYPT);
	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
		{
		int n;

		printf("des_ede3_cbcm_encrypt decrypt error\n");
		for(n=0 ; n < i ; ++n)
		    printf(" %02x",cbc_data[n]);
		printf("\n");
		for(n=0 ; n < i ; ++n)
		    printf(" %02x",cbc_in[n]);
		printf("\n");
		err=1;
		}
#endif

	printf("Doing ecb\n");
	for (i=0; i<NUM_TESTS; i++)
		{
		des_set_key_unchecked(&key_data[i],ks);
		memcpy(in,plain_data[i],8);
		memset(out,0,8);
		memset(outin,0,8);
		des_ecb_encrypt(&in,&out,ks,DES_ENCRYPT);
		des_ecb_encrypt(&out,&outin,ks,DES_DECRYPT);

		if (memcmp(out,cipher_data[i],8) != 0)
			{
			printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
				pt(out));
			err=1;
			}
		if (memcmp(in,outin,8) != 0)
			{
			printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
			err=1;
			}
		}

#ifndef LIBDES_LIT
	printf("Doing ede ecb\n");
	for (i=0; i<(NUM_TESTS-1); i++)
		{
		des_set_key_unchecked(&key_data[i],ks);
		des_set_key_unchecked(&key_data[i+1],ks2);
		des_set_key_unchecked(&key_data[i+2],ks3);
		memcpy(in,plain_data[i],8);
		memset(out,0,8);
		memset(outin,0,8);
		des_ecb2_encrypt(&in,&out,ks,ks2,DES_ENCRYPT);
		des_ecb2_encrypt(&out,&outin,ks,ks2,DES_DECRYPT);

		if (memcmp(out,cipher_ecb2[i],8) != 0)
			{
			printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
				pt(out));
			err=1;
			}
		if (memcmp(in,outin,8) != 0)
			{
			printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
			err=1;
			}
		}
#endif

	printf("Doing cbc\n");
	if ((j=des_set_key_checked(&cbc_key,ks)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	memset(cbc_out,0,40);
	memset(cbc_in,0,40);
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_ncbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
			 &iv3,DES_ENCRYPT);
	if (memcmp(cbc_out,cbc_ok,32) != 0)
		{
		printf("cbc_encrypt encrypt error\n");
		err=1;
		}

	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_ncbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,
			 &iv3,DES_DECRYPT);
	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
		{
		printf("cbc_encrypt decrypt error\n");
		err=1;
		}

#ifndef LIBDES_LIT
	printf("Doing desx cbc\n");
	if ((j=des_set_key_checked(&cbc_key,ks)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	memset(cbc_out,0,40);
	memset(cbc_in,0,40);
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_xcbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
			 &iv3,&cbc2_key,&cbc3_key, DES_ENCRYPT);
	if (memcmp(cbc_out,xcbc_ok,32) != 0)
		{
		printf("des_xcbc_encrypt encrypt error\n");
		err=1;
		}
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_xcbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,
			 &iv3,&cbc2_key,&cbc3_key, DES_DECRYPT);
	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
		{
		printf("des_xcbc_encrypt decrypt error\n");
		err=1;
		}
#endif

	printf("Doing ede cbc\n");
	if ((j=des_set_key_checked(&cbc_key,ks)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	if ((j=des_set_key_checked(&cbc2_key,ks2)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	if ((j=des_set_key_checked(&cbc3_key,ks3)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	memset(cbc_out,0,40);
	memset(cbc_in,0,40);
	i=strlen((char *)cbc_data)+1;
	/* i=((i+7)/8)*8; */
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));

	des_ede3_cbc_encrypt(cbc_data,cbc_out,16L,ks,ks2,ks3,&iv3,DES_ENCRYPT);
	des_ede3_cbc_encrypt(&(cbc_data[16]),&(cbc_out[16]),i-16,ks,ks2,ks3,
			     &iv3,DES_ENCRYPT);
	if (memcmp(cbc_out,cbc3_ok,
		(unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
		{
		printf("des_ede3_cbc_encrypt encrypt error\n");
		err=1;
		}

	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_ede3_cbc_encrypt(cbc_out,cbc_in,i,ks,ks2,ks3,&iv3,DES_DECRYPT);
	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
		{
		printf("des_ede3_cbc_encrypt decrypt error\n");
		err=1;
		}

#ifndef LIBDES_LIT
	printf("Doing pcbc\n");
	if ((j=des_set_key_checked(&cbc_key,ks)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	memset(cbc_out,0,40);
	memset(cbc_in,0,40);
	des_pcbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
			 &cbc_iv,DES_ENCRYPT);
	if (memcmp(cbc_out,pcbc_ok,32) != 0)
		{
		printf("pcbc_encrypt encrypt error\n");
		err=1;
		}
	des_pcbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,&cbc_iv,
			 DES_DECRYPT);
	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
		{
		printf("pcbc_encrypt decrypt error\n");
		err=1;
		}

	printf("Doing ");
	printf("cfb8 ");
	err+=cfb_test(8,cfb_cipher8);
	printf("cfb16 ");
	err+=cfb_test(16,cfb_cipher16);
	printf("cfb32 ");
	err+=cfb_test(32,cfb_cipher32);
	printf("cfb48 ");
	err+=cfb_test(48,cfb_cipher48);
	printf("cfb64 ");
	err+=cfb_test(64,cfb_cipher64);

	printf("cfb64() ");
	err+=cfb64_test(cfb_cipher64);

	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
	for (i=0; i<sizeof(plain); i++)
		des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
			8,1,ks,&cfb_tmp,DES_ENCRYPT);
	if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
		{
		printf("cfb_encrypt small encrypt error\n");
		err=1;
		}

	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
	for (i=0; i<sizeof(plain); i++)
		des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
			8,1,ks,&cfb_tmp,DES_DECRYPT);
	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
		{
		printf("cfb_encrypt small decrypt error\n");
		err=1;
		}

	printf("ede_cfb64() ");
	err+=ede_cfb64_test(cfb_cipher64);

	printf("done\n");

	printf("Doing ofb\n");
	des_set_key_checked(&ofb_key,ks);
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	des_ofb_encrypt(plain,ofb_buf1,64,sizeof(plain)/8,ks,&ofb_tmp);
	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
		{
		printf("ofb_encrypt encrypt error\n");
printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
		err=1;
		}
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	des_ofb_encrypt(ofb_buf1,ofb_buf2,64,sizeof(ofb_buf1)/8,ks,&ofb_tmp);
	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
		{
		printf("ofb_encrypt decrypt error\n");
printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
plain[8+0], plain[8+1], plain[8+2], plain[8+3],
plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
		err=1;
		}

	printf("Doing ofb64\n");
	des_set_key_checked(&ofb_key,ks);
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	memset(ofb_buf1,0,sizeof(ofb_buf1));
	memset(ofb_buf2,0,sizeof(ofb_buf1));
	num=0;
	for (i=0; i<sizeof(plain); i++)
		{
		des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,&ofb_tmp,
				  &num);
		}
	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
		{
		printf("ofb64_encrypt encrypt error\n");
		err=1;
		}
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	num=0;
	des_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,&ofb_tmp,&num);
	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
		{
		printf("ofb64_encrypt decrypt error\n");
		err=1;
		}

	printf("Doing ede_ofb64\n");
	des_set_key_checked(&ofb_key,ks);
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	memset(ofb_buf1,0,sizeof(ofb_buf1));
	memset(ofb_buf2,0,sizeof(ofb_buf1));
	num=0;
	for (i=0; i<sizeof(plain); i++)
		{
		des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks,
				       &ofb_tmp,&num);
		}
	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
		{
		printf("ede_ofb64_encrypt encrypt error\n");
		err=1;
		}
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	num=0;
	des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,
			       ks,ks,&ofb_tmp,&num);
	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
		{
		printf("ede_ofb64_encrypt decrypt error\n");
		err=1;
		}

	printf("Doing cbc_cksum\n");
	des_set_key_checked(&cbc_key,ks);
	cs=des_cbc_cksum(cbc_data,&cret,strlen((char *)cbc_data),ks,&cbc_iv);
	if (cs != cbc_cksum_ret)
		{
		printf("bad return value (%08lX), should be %08lX\n",
			(unsigned long)cs,(unsigned long)cbc_cksum_ret);
		err=1;
		}
	if (memcmp(cret,cbc_cksum_data,8) != 0)
		{
		printf("bad cbc_cksum block returned\n");
		err=1;
		}

	printf("Doing quad_cksum\n");
	cs=quad_cksum(cbc_data,(des_cblock *)lqret,
		(long)strlen((char *)cbc_data),2,(des_cblock *)cbc_iv);
	if (cs != 0x70d7a63aL)
		{
		printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
			(unsigned long)cs);
		err=1;
		}
#ifdef _CRAY
	if (lqret[0].a != 0x327eba8dL)
		{
		printf("quad_cksum error, out[0] %08lx is not %08lx\n",
			(unsigned long)lqret[0].a,0x327eba8dUL);
		err=1;
		}
	if (lqret[0].b != 0x201a49ccL)
		{
		printf("quad_cksum error, out[1] %08lx is not %08lx\n",
			(unsigned long)lqret[0].b,0x201a49ccUL);
		err=1;
		}
	if (lqret[1].a != 0x70d7a63aL)
		{
		printf("quad_cksum error, out[2] %08lx is not %08lx\n",
			(unsigned long)lqret[1].a,0x70d7a63aUL);
		err=1;
		}
	if (lqret[1].b != 0x501c2c26L)
		{
		printf("quad_cksum error, out[3] %08lx is not %08lx\n",
			(unsigned long)lqret[1].b,0x501c2c26UL);
		err=1;
		}
#else
	if (lqret[0] != 0x327eba8dL)
		{
		printf("quad_cksum error, out[0] %08lx is not %08lx\n",
			(unsigned long)lqret[0],0x327eba8dUL);
		err=1;
		}
	if (lqret[1] != 0x201a49ccL)
		{
		printf("quad_cksum error, out[1] %08lx is not %08lx\n",
			(unsigned long)lqret[1],0x201a49ccUL);
		err=1;
		}
	if (lqret[2] != 0x70d7a63aL)
		{
		printf("quad_cksum error, out[2] %08lx is not %08lx\n",
			(unsigned long)lqret[2],0x70d7a63aUL);
		err=1;
		}
	if (lqret[3] != 0x501c2c26L)
		{
		printf("quad_cksum error, out[3] %08lx is not %08lx\n",
			(unsigned long)lqret[3],0x501c2c26UL);
		err=1;
		}
#endif
#endif

	printf("input word alignment test");
	for (i=0; i<4; i++)
		{
		printf(" %d",i);
		des_ncbc_encrypt(&(cbc_out[i]),cbc_in,
				 strlen((char *)cbc_data)+1,ks,
				 &cbc_iv,DES_ENCRYPT);
		}
	printf("\noutput word alignment test");
	for (i=0; i<4; i++)
		{
		printf(" %d",i);
		des_ncbc_encrypt(cbc_out,&(cbc_in[i]),
				 strlen((char *)cbc_data)+1,ks,
				 &cbc_iv,DES_ENCRYPT);
		}
	printf("\n");
	printf("fast crypt test ");
	str=crypt("testing","ef");
	if (strcmp("efGnQx2725bI2",str) != 0)
		{
		printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
		err=1;
		}
	str=crypt("bca76;23","yA");
	if (strcmp("yA1Rp/1hZXIJk",str) != 0)
		{
		printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
		err=1;
		}
	printf("\n");
	return(err);
	}
int
test_main(void)
	{
	int i,j,err=0;
	des_cblock in, out, outin, iv3;
	des_key_schedule ks,ks2,ks3;
	des_cblock cbc_in[5];
	des_cblock cbc_out[5];
	DES_LONG cs;
	unsigned char qret[4][4],cret[8];
	DES_LONG lqret[4];
	int num;
	char *str;

	printf("Doing ecb\n");
	for (i=0; i<NUM_TESTS; i++)
		{
		if ((j=des_key_sched(&key_data[i], ks)) != 0)
			{
			printf("Key error %2d:%d\n",i+1,j);
			err=1;
			}
		memcpy(in,plain_data[i],8);
		memset(out,0,8);
		memset(outin,0,8);
		des_ecb_encrypt(&in, &out, ks, DES_ENCRYPT);
		des_ecb_encrypt(&out, &outin, ks, DES_DECRYPT);

		if (memcmp(out,cipher_data[i],8) != 0)
			{
			printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
				pt(out));
			err=1;
			}
		if (memcmp(in,outin,8) != 0)
			{
			printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
			err=1;
			}
		}

#ifndef LIBDES_LIT
	printf("Doing ede ecb\n");
	for (i=0; i<(NUM_TESTS-1); i++)
		{
		if ((j=des_key_sched(&key_data[i], ks)) != 0)
			{
			err=1;
			printf("Key error %2d:%d\n",i+1,j);
			}
		if ((j=des_key_sched(&key_data[i+1],ks2)) != 0)
			{
			printf("Key error %2d:%d\n",i+2,j);
			err=1;
			}
		if ((j=des_key_sched(&key_data[i+2],ks3)) != 0)
			{
			printf("Key error %2d:%d\n",i+3,j);
			err=1;
			}
		memcpy(in,plain_data[i],8);
		memset(out,0,8);
		memset(outin,0,8);
		des_ecb2_encrypt(&in, &out, ks, ks2,
			DES_ENCRYPT);
		des_ecb2_encrypt(&out, &outin, ks, ks2,
			DES_DECRYPT);

		if (memcmp(out,cipher_ecb2[i],8) != 0)
			{
			printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
				pt(out));
			err=1;
			}
		if (memcmp(in,outin,8) != 0)
			{
			printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
			err=1;
			}
		}
#endif

	printf("Doing cbc\n");
	if ((j=des_key_sched(&cbc_key, ks)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	memset(cbc_out,0,sizeof(cbc_data));
	memset(cbc_in,0,sizeof(cbc_data));
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_ncbc_encrypt(cbc_data, cbc_out,
		sizeof(cbc_data), ks,
		&iv3, DES_ENCRYPT);
	if (memcmp(cbc_out,cbc_ok,32) != 0)
		printf("cbc_encrypt encrypt error\n");

	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_ncbc_encrypt(cbc_out, cbc_in,
		sizeof(cbc_data),ks,
		&iv3,DES_DECRYPT);
	if (memcmp(cbc_in,cbc_data,sizeof(cbc_data)) != 0)
		{
		printf("cbc_encrypt decrypt error\n");
		err=1;
		}

#ifndef LIBDES_LIT
#if 0
	printf("Doing desx cbc\n");
	if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	memset(cbc_out,0,sizeof(cbc_data));
	memset(cbc_in,0,sizeof(cbc_data));
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_xcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
		sizeof(cbc_data), ks,
		(C_Block *)iv3,
		(C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_ENCRYPT);
	if (memcmp(cbc_out,xcbc_ok,32) != 0)
		{
		printf("des_xcbc_encrypt encrypt error\n");
		}
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_xcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
		sizeof(cbc_data), ks,
		(C_Block *)iv3,
		(C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_DECRYPT);
	if (memcmp(cbc_in,cbc_data,sizeof(cbc_data)) != 0)
		{
		printf("des_xcbc_encrypt decrypt error\n");
		err=1;
		}
#endif
#endif /* LIBDES_LIT */

	printf("Doing ede cbc\n");
	if ((j=des_key_sched(&cbc_key,ks)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	if ((j=des_key_sched(&cbc2_key,ks2)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	if ((j=des_key_sched(&cbc3_key,ks3)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	memset(cbc_out,0,sizeof(cbc_data));
	memset(cbc_in,0,sizeof(cbc_data));
	i=sizeof(cbc_data);
	/* i=((i+7)/8)*8; */
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));

	des_ede3_cbc_encrypt( cbc_data, cbc_out,
		16L, ks, ks2, ks3, &iv3, DES_ENCRYPT);
	des_ede3_cbc_encrypt( &cbc_data[2],
		&cbc_out[2],
		(long)i-16, ks, ks2, ks3, &iv3, DES_ENCRYPT);
	if (memcmp(cbc_out,cbc3_ok, sizeof(cbc_data)) != 0)
		{
		printf("des_ede3_cbc_encrypt encrypt error\n");
		err=1;
		}

	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_ede3_cbc_encrypt(cbc_out, cbc_in,
		(long)i, ks, ks2, ks3, &iv3, DES_DECRYPT);
	if (memcmp(cbc_in,cbc_data,sizeof(cbc_data)) != 0)
		{
		printf("des_ede3_cbc_encrypt decrypt error\n");
		err=1;
		}

#ifndef LIBDES_LIT
#if 0
	printf("Doing pcbc\n");
	if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
		{
		printf("Key error %d\n",j);
		err=1;
		}
	memset(cbc_out,0,sizeof(cbc_data));
	memset(cbc_in,0,sizeof(cbc_data));
	des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
		sizeof(cbc_data),ks,(C_Block *)cbc_iv,DES_ENCRYPT);
	if (memcmp(cbc_out,pcbc_ok,32) != 0)
		{
		printf("pcbc_encrypt encrypt error\n");
		err=1;
		}
	des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
		sizeof(cbc_data),ks,(C_Block *)cbc_iv,DES_DECRYPT);
	if (memcmp(cbc_in,cbc_data,sizeof(cbc_data)) != 0)
		{
		printf("pcbc_encrypt decrypt error\n");
		err=1;
		}

	printf("Doing ");
	printf("cfb8 ");
	err+=cfb_test(8,cfb_cipher8);
	printf("cfb16 ");
	err+=cfb_test(16,cfb_cipher16);
	printf("cfb32 ");
	err+=cfb_test(32,cfb_cipher32);
	printf("cfb48 ");
	err+=cfb_test(48,cfb_cipher48);
	printf("cfb64 ");
	err+=cfb_test(64,cfb_cipher64);

	printf("cfb64() ");
	err+=cfb64_test(cfb_cipher64);

	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
	for (i=0; i<sizeof(plain); i++)
		des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
			8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT);
	if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
		{
		printf("cfb_encrypt small encrypt error\n");
		err=1;
		}

	memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
	for (i=0; i<sizeof(plain); i++)
		des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
			8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT);
	if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
		{
		printf("cfb_encrypt small decrypt error\n");
		err=1;
		}

	printf("ede_cfb64() ");
	err+=ede_cfb64_test(cfb_cipher64);

	printf("done\n");

	printf("Doing ofb\n");
	des_key_sched((C_Block *)ofb_key,ks);
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	des_ofb_encrypt(plain,ofb_buf1,64,(long)sizeof(plain)/8,ks,
		(C_Block *)ofb_tmp);
	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
		{
		printf("ofb_encrypt encrypt error\n");
porintf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
		err=1;
		}
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks,
		(C_Block *)ofb_tmp);
	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
		{
		printf("ofb_encrypt decrypt error\n");
printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
plain[8+0], plain[8+1], plain[8+2], plain[8+3],
plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
		err=1;
		}

	printf("Doing ofb64\n");
	des_key_sched((C_Block *)ofb_key,ks);
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	memset(ofb_buf1,0,sizeof(ofb_buf1));
	memset(ofb_buf2,0,sizeof(ofb_buf1));
	num=0;
	for (i=0; i<sizeof(plain); i++)
		{
		des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,
			(C_Block *)ofb_tmp,&num);
		}
	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
		{
		printf("ofb64_encrypt encrypt error\n");
		err=1;
		}
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	num=0;
	des_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
		(C_Block *)ofb_tmp,&num);
	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
		{
		printf("ofb64_encrypt decrypt error\n");
		err=1;
		}

	printf("Doing ede_ofb64\n");
	des_key_sched((C_Block *)ofb_key,ks);
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	memset(ofb_buf1,0,sizeof(ofb_buf1));
	memset(ofb_buf2,0,sizeof(ofb_buf1));
	num=0;
	for (i=0; i<sizeof(plain); i++)
		{
		des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks,
			(C_Block *)ofb_tmp,&num);
		}
	if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
		{
		printf("ede_ofb64_encrypt encrypt error\n");
		err=1;
		}
	memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	num=0;
	des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
		ks,ks,(C_Block *)ofb_tmp,&num);
	if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
		{
		printf("ede_ofb64_encrypt decrypt error\n");
		err=1;
		}
#endif
        
	printf("Doing cbc_cksum\n");
	des_key_sched(&cbc_key,ks);
	cs=des_cbc_cksum(cbc_data[0], &cret,
		sizeof(cbc_data), ks, &cbc_iv);
	if (cs != cbc_cksum_ret)
		{
		printf("bad return value (%08lX), should be %08lX\n",
			(unsigned long)cs,(unsigned long)cbc_cksum_ret);
		err=1;
		}
	if (memcmp(cret,cbc_cksum_data,8) != 0)
		{
		printf("bad cbc_cksum block returned\n");
		err=1;
		}

#if 0
	printf("Doing quad_cksum\n");
	cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret,
		sizeof(cbc_data),2,(C_Block *)cbc_iv);
	for (i=0; i<4; i++)
		{
		lqret[i]=0;
		memcpy(&(lqret[i]),&(qret[i][0]),4);
		}
	{ /* Big-endian fix */
	static DES_LONG l=1;
	static unsigned char *c=(unsigned char *)&l;
	DES_LONG ll;

	if (!c[0])
		{
		ll=lqret[0]^lqret[3];
		lqret[0]^=ll;
		lqret[3]^=ll;
		ll=lqret[1]^lqret[2];
		lqret[1]^=ll;
		lqret[2]^=ll;
		}
	}
	if (cs != 0x70d7a63aL)
		{
		printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
			(unsigned long)cs);
		err=1;
		}
	if (lqret[0] != 0x327eba8dL)
		{
		printf("quad_cksum error, out[0] %08lx is not %08lx\n",
			(unsigned long)lqret[0],0x327eba8dL);
		err=1;
		}
	if (lqret[1] != 0x201a49ccL)
		{
		printf("quad_cksum error, out[1] %08lx is not %08lx\n",
			(unsigned long)lqret[1],0x201a49ccL);
		err=1;
		}
	if (lqret[2] != 0x70d7a63aL)
		{
		printf("quad_cksum error, out[2] %08lx is not %08lx\n",
			(unsigned long)lqret[2],0x70d7a63aL);
		err=1;
		}
	if (lqret[3] != 0x501c2c26L)
		{
		printf("quad_cksum error, out[3] %08lx is not %08lx\n",
			(unsigned long)lqret[3],0x501c2c26L);
		err=1;
		}
#endif
#endif /* LIBDES_LIT */
#if 0
	printf("input word alignment test");
	for (i=0; i<4; i++)
		{
		printf(" %d",i);
		des_ncbc_encrypt( (des_cblock *) &(cbc_out[i]), (des_cblock *) cbc_in,
			sizeof(cbc_data), ks, &cbc_iv,
			DES_ENCRYPT);
		}
	printf("\noutput word alignment test");
	for (i=0; i<4; i++)
		{
		printf(" %d",i);
		des_ncbc_encrypt( (des_cblock *) cbc_out, (des_cblock *) &(cbc_in[i]),
			sizeof(cbc_data), ks, &cbc_iv,
			DES_ENCRYPT);
		}
	printf("\n");

	printf("fast crypt test ");
	str=crypt("testing","ef");
	if (strcmp("efGnQx2725bI2",str) != 0)
		{
		printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
		err=1;
		}
	str=crypt("bca76;23","yA");
	if (strcmp("yA1Rp/1hZXIJk",str) != 0)
		{
		printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
		err=1;
		}
	printf("\n");
#endif
	exit(err);
	return(0);
	}
Ejemplo n.º 12
0
int32 destest(void) {
	int i,j,err=0;
	des_cblock in,out,outin,iv3,iv2;
	des_key_schedule ks,ks2,ks3;
	char cbc_in[40], simCbc_in[40], simEmbIVCbc_in[64];
	char cbc_out[40], simCbc_out[40], simEmbIVCbc_out[64];
	int8 desSimCipherData[8], desSimPlainData[8], key[24];

	rtlglue_printf("Doing ecb\n");
	for (i=0; i<NUM_TESTS; i++) {
		int8 desSimCipherData[8], desSimPlainData[8];
		
		des_set_key(key_data[i], ks);
		memcpy(in, plain_data[i],8);
		memset(out,0,8);
		memset(outin,0,8);
		des_ecb_encrypt(&in,&out,ks,DES_ENCRYPT);
		des_ecb_encrypt(&out,&outin,ks,DES_DECRYPT);
		
		if(desSim_ecb_encrypt(plain_data[i], &desSimCipherData[0], 8, key_data[i], TRUE) != SUCCESS)
			rtlglue_printf("desSimulator ecb encrypt failed\n");
		if(desSim_ecb_encrypt(cipher_data[i], &desSimPlainData[0], 8, key_data[i], FALSE) != SUCCESS)
			rtlglue_printf("desSimulator ecb decrypt failed\n");
			
		if (memcmp(out,cipher_data[i],8) != 0) {
			rtlglue_printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt((char *)in),pt(cipher_data[i]),
				pt((char *)out));
			err=1;
		}
		
		if (memcmp(in,outin,8) != 0) {
			rtlglue_printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt((char *)out),pt((char *)in),pt((char *)outin));
			err=1;
		}

		if(memcmp(&desSimCipherData[0], &cipher_data[i], 8) != 0) {
			rtlglue_printf("desSim ecb Encryption error %2d\nk=%s plain=%s Expect cipher=%s crypt result=%s\n",
				i+1,pt(key_data[i]),pt(plain_data[8]),pt(cipher_data[i]), pt(&desSimCipherData[0]));
			err=1;
		}

		if(memcmp(&desSimPlainData[0], plain_data[i], 8) != 0) {
			rtlglue_printf("desSim ecb Decryption error %2d\nk=%s Crypted data=%s Expect plain=%s decrypt result=%s\n",
				i+1,pt(key_data[i]),pt(cipher_data[i]),pt(plain_data[i]), pt(&desSimPlainData[0]));
			err=1;
		}
	}

	rtlglue_printf("Doing ede ecb\n");
	for (i=0; i<(NUM_TESTS-1); i++)	{

		des_set_key((int8*)&key_data[i], ks);
		des_set_key((int8*)&key_data[i+1], ks2);
//		des_set_key(&key_data[i+2], ks3);	//This code is useless...legacy?
		memcpy(in,plain_data[i],8);
		memset(out,0,8);
		memset(outin,0,8);
		des_ecb2_encrypt(&in,&out,ks,ks2,DES_ENCRYPT);
		des_ecb2_encrypt(&out,&outin,ks,ks2,DES_DECRYPT);

		memcpy(&key[0], &key_data[i], 8);
		memcpy(&key[8], &key_data[i+1], 8);
		memcpy(&key[16], &key_data[i], 8);
		if(desSim_ede_ecb_encrypt(plain_data[i], &desSimCipherData[0], 8, &key[0], TRUE) != SUCCESS)
			rtlglue_printf("desSimulator ede ecb encrypt failed\n");
		if(desSim_ede_ecb_encrypt(cipher_ecb2[i], &desSimPlainData[0], 8, &key[0], FALSE) != SUCCESS)
			rtlglue_printf("desSimulator ede ecb decrypt failed\n");
			
		if (memcmp(out,cipher_ecb2[i],8) != 0)
			{
			rtlglue_printf("Encryption error %2d\nk=%s %s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(key_data[i+1]),pt(in),pt(cipher_ecb2[i]),
				pt(out));
			err=1;
			}
		if (memcmp(in,outin,8) != 0)
			{
			rtlglue_printf("Decryption error %2d\nk=%s %s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(key_data[i+1]),pt(out),pt(in),pt(outin));
			err=1;
			}
		if(memcmp(&desSimCipherData[0], &cipher_ecb2[i], 8) != 0) {
			rtlglue_printf("desSim cbc ecb encryption error %2d\nk=%s plain=%s Expect cipher=%s crypt result=%s\n",
				i+1,pt(key_data[i]),pt(plain_data[8]),pt(cipher_ecb2[i]), pt(&desSimCipherData[0]));
			err=1;
		}

		if(memcmp(&desSimPlainData[0], plain_data[i], 8) != 0) {
			rtlglue_printf("desSim cbc ecb decryption error %2d\nk=%s Crypted data=%s Expect plain=%s decrypt result=%s\n",
				i+1,pt(key_data[i]),pt(cipher_ecb2[i]),pt(plain_data[i]), pt(&desSimPlainData[0]));
			err=1;
		}
	}

	rtlglue_printf("Doing cbc\n");
	if ((j=des_set_key(&cbc_key, ks)) != 0)
		rtlglue_printf("Key error %d\n",j);

	memset(cbc_out,0,40);
	memset(cbc_in,0,40);
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_ncbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks, &iv3, TRUE);
	if (memcmp(cbc_out,cbc_ok,32) != 0)
		rtlglue_printf("cbc_encrypt encrypt error\n");

	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_ncbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks, &iv3, FALSE);
	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
		rtlglue_printf("cbc_encrypt decrypt error\n");

	if(desSim_cbc_encrypt(cbc_data, simCbc_out, strlen((char *)cbc_data)+1, &cbc_key[0], &cbc_iv[0], TRUE) != SUCCESS)
		rtlglue_printf("desSim cbc encryption error\n");
	if (memcmp(simCbc_out,cbc_ok,32) != 0)
		rtlglue_printf("desSim cbc encrypt result error\n");

	memcpy(&simEmbIVCbc_in[0], &cbc_iv[0], 8);
	memcpy(&simEmbIVCbc_in[8], &cbc_data[0], 40);
	if(desSim_cbc_encryptEmbIV(&simEmbIVCbc_in[0], &simEmbIVCbc_out[0], strlen((char *)cbc_data)+9, &cbc_key[0], TRUE) != SUCCESS)
		rtlglue_printf("desSim cbc embed IV encrypt failed\n");
	if (memcmp(&simEmbIVCbc_out[8], cbc_ok,32) != 0)
		rtlglue_printf("desSim cbc embed IV encrypt result error\n");
	
	//CBC Decrypt
	if(desSim_cbc_encrypt(simCbc_out, simCbc_in, strlen((char *)cbc_data)+1, &cbc_key[0], &cbc_iv[0], FALSE) != SUCCESS) 
		rtlglue_printf("desSim cbc decryption error\n");
	if (memcmp(simCbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
		rtlglue_printf("desSim cbc decrypt error\n");

	memcpy(&simEmbIVCbc_out[0], &cbc_iv[0], 8);
	if(desSim_cbc_encryptEmbIV(&simEmbIVCbc_out[0], &simEmbIVCbc_in[0], strlen((char *)cbc_data)+9, &cbc_key[0], FALSE) != SUCCESS)
		rtlglue_printf("desSim cbc embed IV decrypt failed\n");
	if (memcmp(&simEmbIVCbc_in[8], cbc_data,strlen((char *)cbc_data)) != 0)
		rtlglue_printf("desSim cbc embed IV decrypt error\n");
	
	
	rtlglue_printf("Doing ede cbc\n");
	if ((j=des_set_key(&cbc_key, ks)) != 0)
		rtlglue_printf("Key1 error %d\n",j);
	if ((j=des_set_key(&cbc2_key, ks2)) != 0)
		rtlglue_printf("Key2 error %d\n",j);
	if ((j=des_set_key(&cbc3_key, ks3)) != 0)
		rtlglue_printf("Key3 error %d\n",j);
	memset(cbc_out,0,40);
	memset(cbc_in,0,40);
	i=strlen((char *)cbc_data)+1;
	/* i=((i+7)/8)*8; */
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));

	des_ede3_cbc_encrypt(cbc_data,cbc_out,i,ks,ks2,ks3,&iv3, DES_ENCRYPT);
//	des_ede3_cbc_encrypt(cbc_data,cbc_out,16L,ks,ks2,ks3,&iv3, DES_ENCRYPT);
//	des_ede3_cbc_encrypt(&(cbc_data[16]),&(cbc_out[16]),i-16,ks,ks2,ks3, &iv3,DES_ENCRYPT);
	if (memcmp(cbc_out,cbc3_ok,
		(unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
		{
		int n;

		rtlglue_printf("des_ede3_cbc_encrypt encrypt error\n");
		for(n=0 ; n < i ; ++n)
		    rtlglue_printf(" %02x",cbc_out[n]);
		rtlglue_printf("\n");
		for(n=0 ; n < i ; ++n)
		    rtlglue_printf(" %02x",cbc3_ok[n]);
		rtlglue_printf("\n");
		err=1;
		}

	memcpy(&key[0], &cbc_key[0], 8);
	memcpy(&key[8], &cbc2_key[0], 8);
	memcpy(&key[16], &cbc3_key[0], 8);
	if(desSim_ede_cbc_encrypt(&cbc_data[0], &simCbc_out[0], strlen((char *)cbc_data)+1, &key[0], &cbc_iv[0], TRUE) != SUCCESS)
		rtlglue_printf("desSim ede cbc encrypt failed\n");
	if(memcmp(simCbc_out, cbc3_ok, (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
		rtlglue_printf("desSim ede cbc encrypt result error\n");

	memcpy(&simEmbIVCbc_in[0], &cbc_iv[0], 8);
	memcpy(&simEmbIVCbc_in[8], &cbc_data[0], 40);
	if(desSim_ede_cbc_encryptEmbIV(&simEmbIVCbc_in[0], &simEmbIVCbc_out[0], strlen((char *)cbc_data)+1+8, &key[0], TRUE) != SUCCESS)
		rtlglue_printf("desSim ede cbc embed IV encrypt failed\n");
	if(memcmp(&simEmbIVCbc_out[8], cbc3_ok, (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
		rtlglue_printf("desSim ede cbc embed IV encrypt result error\n");
	
	
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_ede3_cbc_encrypt(cbc_out,cbc_in,i,ks,ks2,ks3,&iv3,FALSE);
	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0) {
		int n;

		rtlglue_printf("des_ede3_cbc_encrypt decrypt error\n");
		for(n=0 ; n < i ; ++n)
		    rtlglue_printf(" %02x",cbc_data[n]);
		rtlglue_printf("\n");
		for(n=0 ; n < i ; ++n)
		    rtlglue_printf(" %02x",cbc_in[n]);
		rtlglue_printf("\n");
		err=1;
	}

	if(desSim_ede_cbc_encrypt(&simCbc_out[0], &simCbc_in[0], i, &key[0], &cbc_iv[0], FALSE) != SUCCESS)
		rtlglue_printf("desSim ede cbc decrypt failed\n");
	if(memcmp(simCbc_in, cbc_data, strlen((char *)cbc_data)+1) != 0) {
		int n;
		rtlglue_printf("desSim ede cbc decrypt result error\n");
		for(n=0 ; n < i ; ++n)
		    rtlglue_printf(" %02x",cbc_data[n]);
		rtlglue_printf("\n");
		for(n=0 ; n < i ; ++n)
		    rtlglue_printf(" %02x",simCbc_in[n]);
		rtlglue_printf("\n");
	}

	memcpy(&simEmbIVCbc_out[0], &cbc_iv[0], 8);
	if(desSim_ede_cbc_encryptEmbIV(&simEmbIVCbc_out[0], &simEmbIVCbc_in[0], i+8, &key[0], FALSE) != SUCCESS)
		rtlglue_printf("desSim ede cbc embed IV decrypt failed\n");
	if(memcmp(&simEmbIVCbc_in[8], cbc_data, strlen((char *)cbc_data)+1) != 0) {
		int n;
		rtlglue_printf("desSim ede cbc embed IV decrypt result error\n");
		for(n=0 ; n < i ; ++n)
		    rtlglue_printf(" %02x",cbc_data[n]);
		rtlglue_printf("\n");
		for(n=0 ; n < i ; ++n)
		    rtlglue_printf(" %02x",simEmbIVCbc_in[n+8]);
		rtlglue_printf("\n");
	}

	//Crypto engine not implemented part
	rtlglue_printf("No crypto engine verification part\n");
	rtlglue_printf("Doing cbcm\n");
	if ((j=des_set_key(&cbc_key, ks)) != 0)
		{
		rtlglue_printf("Key error %d\n",j);
		err=1;
		}
	if ((j=des_set_key(&cbc2_key, ks2)) != 0)
		{
		rtlglue_printf("Key error %d\n",j);
		err=1;
		}
	if ((j=des_set_key(&cbc3_key, ks3)) != 0)
		{
		rtlglue_printf("Key error %d\n",j);
		err=1;
		}
	memset(cbc_out,0,40);
	memset(cbc_in,0,40);
	i=strlen((char *)cbc_data)+1;
	/* i=((i+7)/8)*8; */
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	memset(iv2,'\0',sizeof iv2);

	des_ede3_cbcm_encrypt(cbc_data,cbc_out,16L,&ks,&ks2,&ks3,&iv3,&iv2,
			      DES_ENCRYPT);
	des_ede3_cbcm_encrypt(&cbc_data[16],&cbc_out[16],i-16,&ks,&ks2,&ks3,
			      &iv3,&iv2,DES_ENCRYPT);
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	memset(iv2,'\0',sizeof iv2);
	des_ede3_cbcm_encrypt(cbc_out,cbc_in,i,&ks,&ks2,&ks3,&iv3,&iv2,DES_DECRYPT);
	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0) {
		int n;

		rtlglue_printf("des_ede3_cbcm_encrypt decrypt error\n");
		for(n=0 ; n < i ; ++n)
		    rtlglue_printf(" %02x",cbc_data[n]);
		rtlglue_printf("\n");
		for(n=0 ; n < i ; ++n)
		    rtlglue_printf(" %02x",cbc_in[n]);
		rtlglue_printf("\n");
		err=1;
	} 
	rtlglue_printf("Doing desx cbc\n");
	if ((j=des_set_key(&cbc_key, ks)) != 0) {
		rtlglue_printf("Key error %d\n",j);
		err=1;
	}
	memset(cbc_out,0,40);
	memset(cbc_in,0,40);
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_xcbc_encrypt(cbc_data,cbc_out,strlen((char *)cbc_data)+1,ks,
			 &iv3,&cbc2_key,&cbc3_key, DES_ENCRYPT);
	if (memcmp(cbc_out,xcbc_ok,32) != 0) {
		rtlglue_printf("des_xcbc_encrypt encrypt error\n");
		err=1;
	}
	memcpy(iv3,cbc_iv,sizeof(cbc_iv));
	des_xcbc_encrypt(cbc_out,cbc_in,strlen((char *)cbc_data)+1,ks,
			 &iv3,&cbc2_key,&cbc3_key, DES_DECRYPT);
	if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0) {
		rtlglue_printf("des_xcbc_encrypt decrypt error\n");
		err=1;
	}

	return(err);
}
Ejemplo n.º 13
0
/* {{{ CI_Ceay_Decrypt */
CK_DEFINE_FUNCTION(CK_RV, CI_Ceay_Decrypt)(
  CK_I_SESSION_DATA_PTR  session_data,
  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
  CK_BYTE_PTR       pData,              /* gets plaintext */
  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
)
{
  CK_RV rv;

  switch(session_data->decrypt_mechanism)
    {
      /* {{{ CKM_RSA_PKCS */
    case CKM_RSA_PKCS:
      {
	CK_BYTE_PTR tmp_buf = NULL_PTR;
	CK_ULONG key_len;
	long processed; /* number of bytes processed by the crypto routine */
	
	rv = CKR_OK;
	
	CI_LogEntry("C_Decrypt", "RSA PKCS", rv , 0);     
	key_len = CI_Ceay_RSA_size((RSA CK_PTR)session_data->decrypt_state);
	
	/* check if this is only a call for the length of the output buffer */
	if(pData == NULL_PTR)
	  {
	    *pulDataLen = key_len-CK_I_PKCS1_MIN_PADDING;
	    CI_VarLogEntry("C_Decrypt", "RSA PKCS Datalength calculated (%i)", 
			   rv , 0, *pulDataLen);
	    CI_LogEntry("C_Decrypt", "...completed", rv , 0);         
	    return CKR_OK;
	  }
	
	/* check for length of input */
	if(ulEncryptedDataLen != key_len)
	  { rv = CKR_DATA_LEN_RANGE; goto rsa_pkcs1_err; }
	
	tmp_buf = CI_ByteStream_new(key_len);
	
	processed = RSA_private_decrypt(ulEncryptedDataLen,pEncryptedData, 
					tmp_buf,session_data->decrypt_state, 
					RSA_PKCS1_PADDING);
	
	if(processed == -1)
	  { 
	    rv = CKR_GENERAL_ERROR; 
	    goto rsa_pkcs1_err; 
	  }
	
	if(*pulDataLen < (unsigned long)processed) 
	  {
	    *pulDataLen = processed;
	    rv = CKR_BUFFER_TOO_SMALL;
	    goto rsa_pkcs1_err; 
	  }
	
	*pulDataLen = processed;
	
	memcpy(pData, tmp_buf, processed);
	
      rsa_pkcs1_err:
	if(tmp_buf != NULL_PTR) 
	  TC_free(tmp_buf);
	if(session_data->decrypt_state != NULL_PTR)
	  { 
	    RSA_free(session_data->decrypt_state); 
	    session_data->decrypt_state = NULL_PTR;
	  }
	break;
      }
      
      /* }}} */
      /* {{{ CKM_RSA_X_509 */
    case CKM_RSA_X_509:
      {
	CK_BYTE_PTR tmp_buf = NULL_PTR;
	CK_ULONG key_len;
	long processed; /* number of bytes processed by the crypto routine */

	CI_LogEntry("C_Decrypt", "RSA X509", rv , 0);     

	rv = CKR_OK;
	key_len = RSA_size((RSA CK_PTR)session_data->decrypt_state);

	/* terminate operation */
	if(pulDataLen == NULL_PTR) 
	  {
	    rv = CKR_OK; goto rsa_x509_err;
	  }

	/* check if this is only a call for the length of the output buffer */
	if(pData == NULL_PTR)
	  {
	    *pulDataLen = key_len;
	    rv = CKR_OK; break;
	  }
	else /* check that buffer is of sufficent size */
	  {
	    if(*pulDataLen < key_len)
	      {
		*pulDataLen = key_len;
		rv = CKR_BUFFER_TOO_SMALL; break;
	      }
	  }
	
	/* check for length of input */
	if(ulEncryptedDataLen != key_len)
	  { rv = CKR_DATA_LEN_RANGE; goto rsa_x509_err; }
	
	tmp_buf = CI_ByteStream_new(key_len);
	if(tmp_buf == NULL_PTR) { rv = CKR_HOST_MEMORY; goto rsa_x509_err; }
	
	processed = RSA_private_decrypt(ulEncryptedDataLen,pEncryptedData,
					tmp_buf,session_data->decrypt_state,
					RSA_NO_PADDING);
	if(processed == -1)
	  { rv = CKR_GENERAL_ERROR; goto rsa_x509_err; }
	*pulDataLen = processed;

	memcpy(pData,tmp_buf,key_len);
	
      rsa_x509_err:
	if(tmp_buf != NULL_PTR) TC_free(tmp_buf);
	if(session_data->decrypt_state != NULL_PTR)
	  { 
	    RSA_free(session_data->decrypt_state); 
	    session_data->decrypt_state = NULL_PTR;
	  }
	break;
      }
      /* }}} */
      /* {{{ CKM_RC4 */
    case CKM_RC4:
      {
	/* terminate operation */
	if(pulDataLen == NULL_PTR) 
	  {
	    rv = CKR_OK; goto rc4_err;
	  }
	/* is this just a test for the length of the recieving buffer? */

    rv = CKR_OK;
	CI_LogEntry("C_Decrypt", "RC4", rv , 0);	  

	if(pData == NULL_PTR)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_OK; break;
	  }
	
	/* is the supplied buffer long enough? */
	if(*pulDataLen < ulEncryptedDataLen)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_BUFFER_TOO_SMALL; break;
	  }

	/* OK all set. lets compute */
	RC4(session_data->decrypt_state,ulEncryptedDataLen,pEncryptedData,pData);
	
	*pulDataLen=ulEncryptedDataLen;
	rv = CKR_OK;

rc4_err:
	if(session_data->decrypt_state != NULL_PTR)
	  TC_free(session_data->decrypt_state);
	session_data->decrypt_state = NULL_PTR;

      }
      break;
      /* }}} */
      /* {{{ CKM_RC2_ECB */
    case CKM_RC2_ECB:
      {
	CK_ULONG count;

	/* terminate operation */
	if(pulDataLen == NULL_PTR) 
	  {
	    rv = CKR_OK; goto rc2_cbc_err;
	  }
	/* RC2 always takes multiples of 8 bytes */
	if(ulEncryptedDataLen%8 != 0)
	  { rv = CKR_DATA_LEN_RANGE; goto rc2_ecb_err; }

	/* is this just a test for the length of the recieving buffer? */
	if(pData == NULL_PTR)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_OK; break;
	  }
	
	/* is the supplied buffer long enough? */
	if(*pulDataLen < ulEncryptedDataLen)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_BUFFER_TOO_SMALL; break;
	  }

	/* OK all set. lets compute */
	/* in blocks of 8 bytes. */
	for(count=0; count<ulEncryptedDataLen ; count+=8)
	  {
	    RC2_ecb_encrypt(&(pEncryptedData[count]),&(pData[count]), 
			    session_data->decrypt_state,
			    RC2_DECRYPT);	    
	  }
	
	*pulDataLen=ulEncryptedDataLen;
	rv = CKR_OK;

    rc2_ecb_err:
	if(session_data->decrypt_state != NULL_PTR)
	  TC_free(session_data->decrypt_state);
	session_data->decrypt_state = NULL_PTR;

      }
      break;
      /* }}} */
      /* {{{ CKM_RC2_CBC */
    case CKM_RC2_CBC:
      {
	/* terminate operation */
	if(pulDataLen == NULL_PTR) 
	  {
	    rv = CKR_OK; goto rc2_cbc_err;
	  }
	/* is the length of the supplied data a multiple of 8 to create des-blocks? */
	if(ulEncryptedDataLen%8 != 0)
	  { rv = CKR_DATA_LEN_RANGE; goto rc2_cbc_err; }

	/* is this just a test for the length of the recieving buffer? */
	if(pData == NULL_PTR)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_OK; break;
	  }

	/* is the supplied buffer long enough? */
	if(*pulDataLen < ulEncryptedDataLen)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_BUFFER_TOO_SMALL; break;
	  }

	/* OK all set. lets compute */
	RC2_cbc_encrypt((unsigned char*)pEncryptedData, (unsigned char*)pData, 
			 ulEncryptedDataLen, 
			 ((CK_I_CEAY_RC2_INFO_PTR)session_data->decrypt_state)->key, 
			 ((CK_I_CEAY_RC2_INFO_PTR)session_data->decrypt_state)->ivec, 
			 RC2_DECRYPT);

	rv = CKR_OK;

    rc2_cbc_err:
	CI_RC2_INFO_delete(session_data->decrypt_state);
	session_data->decrypt_state = NULL_PTR;

      }
      break;
      /* }}} */
      /* {{{ CKM_DES_ECB */
    case CKM_DES_ECB:
      {
	CK_ULONG count;

	/* terminate operation */
	if(pulDataLen == NULL_PTR) 
	  {
	    rv = CKR_OK; goto des_ecb_err;
	  }
	/* DES allways takes multiples of 8 bytes */
	if(ulEncryptedDataLen%8 != 0)
	  {
	    rv = CKR_DATA_LEN_RANGE; goto des_ecb_err;
	  }

	/* is this just a test for the length of the recieving buffer? */
	if(pData == NULL_PTR)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_OK; break;
	  }
	
	/* is the supplied buffer long enough? */
	if(*pulDataLen < ulEncryptedDataLen)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_BUFFER_TOO_SMALL; break;
	  }

	/* OK all set. lets compute */
	/* in blocks of 8 bytes. */
	for(count=0; count<ulEncryptedDataLen ; count+=8)
	  {
	    des_ecb_encrypt((des_cblock*)(&(pEncryptedData[count])),
			    (des_cblock*)(&(pData[count])),
			    session_data->decrypt_state,
			    DES_DECRYPT);
	  }
	
	*pulDataLen=ulEncryptedDataLen;

	rv = CKR_OK;

      des_ecb_err:
	if(session_data->decrypt_state != NULL_PTR)
	  TC_free(session_data->decrypt_state);
	session_data->decrypt_state = NULL_PTR;

      }
      break;
      /* }}} */
      /* {{{ CKM_DES_CBC */
    case CKM_DES_CBC:
      {
	/* terminate operation */
	if(pulDataLen == NULL_PTR) 
	  {
	    rv = CKR_OK; goto des_cbc_err;
	  }
	/* is the length of the supplied data a multiple of 8 to create des-blocks? */
	if(ulEncryptedDataLen%8 != 0)
	  {
	    rv = CKR_DATA_LEN_RANGE; goto des_cbc_err;
	  }

	/* is this just a test for the length of the recieving buffer? */
	if(pData == NULL_PTR)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_OK; break;
	  }

	/* is the supplied buffer long enough? */
	if(*pulDataLen < ulEncryptedDataLen)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_BUFFER_TOO_SMALL; break;
	  }

	/* OK all set. lets compute */
	des_ncbc_encrypt(pEncryptedData, 
			 pData, 
			 ulEncryptedDataLen, 
			 ((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->sched, 
			 &(((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->ivec), 
			 DES_DECRYPT);

	*pulDataLen=ulEncryptedDataLen;

	rv = CKR_OK;

      des_cbc_err:
	if(session_data->decrypt_state!= NULL_PTR)
	  TC_free(session_data->decrypt_state);
	session_data->decrypt_state = NULL_PTR;
	
      }
      break;
      /* }}} */
      /* {{{ CKM_DES_CBC_PAD */
    case CKM_DES_CBC_PAD:
      {
	CK_BYTE PadValue;
	CK_ULONG ulPaddingLen, i;

	/* terminate operation */
	if(pulDataLen == NULL_PTR) 
	  {
	    rv = CKR_OK; goto des_cbc_pad_err;
	  }
	/* is the length of the supplied data a multiple of 8 to create des-blocks? */
	if(ulEncryptedDataLen%8 != 0)
	  {
	    rv = CKR_DATA_LEN_RANGE; break;
	  }

	/* is this just a test for the length of the recieving buffer? */
	if(pData == NULL_PTR)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_OK; break;
	  }

	/* is the supplied buffer long enough? */
	if(*pulDataLen < ulEncryptedDataLen)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_BUFFER_TOO_SMALL; goto des_cbc_pad_err;
	  }

	/* OK all set. lets compute */
	des_ncbc_encrypt(pEncryptedData, 
			 pData, 
			 ulEncryptedDataLen, 
			 ((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->sched, 
			 &(((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->ivec), 
			 DES_DECRYPT);

	if((CK_BYTE)((pData[ulEncryptedDataLen-1] >= 1 ) && (CK_BYTE)(pData[ulEncryptedDataLen-1] <= 8)))
	{ 
	  PadValue = (CK_BYTE)(pData[ulEncryptedDataLen-1]);
	  ulPaddingLen = (CK_ULONG)PadValue;
	}
	else
	  { ulPaddingLen = 0; }

	for (i=0; i<ulPaddingLen; i++)
	  if ((CK_BYTE)(pData[ulEncryptedDataLen-1-i]) != PadValue)
	  { rv = CKR_GENERAL_ERROR; goto des_cbc_pad_err; }

	*pulDataLen=ulEncryptedDataLen-ulPaddingLen;

	rv = CKR_OK;

      des_cbc_pad_err:
	if(session_data->decrypt_state!= NULL_PTR)
	  TC_free(session_data->decrypt_state);
	session_data->decrypt_state = NULL_PTR;

      }
      break;
      /* }}} */
      /* {{{ CKM_DES3_ECB */
    case CKM_DES3_ECB:
      {
	CK_ULONG count;

	/* terminate operation */
	if(pulDataLen == NULL_PTR) 
	  {
	    rv = CKR_OK; goto des3_ecb_err;
	  }
	/* DES always takes multiples of 8 bytes */
	if(ulEncryptedDataLen%8 != 0)
	  {
	    rv = CKR_DATA_LEN_RANGE; goto des3_ecb_err;
	  }

	/* is this just a test for the length of the recieving buffer? */
	if(pData == NULL_PTR)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_OK; break;
	  }
	
	/* is the supplied buffer long enough? */
	if(*pulDataLen < ulEncryptedDataLen)
	  {
	    *pulDataLen = ulEncryptedDataLen;	    
	    rv = CKR_BUFFER_TOO_SMALL; break;
	  }

	/* OK all set. lets compute */
	/* in blocks of 8 bytes. */
	for(count=0; count<ulEncryptedDataLen ; count+=8)
	  {
	    des_ecb3_encrypt((des_cblock*)(&(pEncryptedData[count])),
			     (des_cblock*)(&(pData[count])),
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[0],
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[1],
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[2],
			     DES_DECRYPT);
	  }
	
	*pulDataLen=ulEncryptedDataLen;

	rv = CKR_OK;
      des3_ecb_err:
	if(session_data->decrypt_state!= NULL_PTR)
	  CI_DES3_INFO_delete(session_data->decrypt_state);
	session_data->decrypt_state = NULL_PTR;

      }
      break;
      /* }}} */
      /* {{{ CKM_DES3_CBC */
    case CKM_DES3_CBC:
      {
	/* terminate operation */
	if(pulDataLen == NULL_PTR) 
	  {
	    rv = CKR_OK; goto des3_cbc_err;
	  }
	/* is the length of the supplied data a multiple of 8 to create des-blocks? */
	if(ulEncryptedDataLen%8 != 0)
	  {
	    rv = CKR_DATA_LEN_RANGE; goto des3_cbc_err;
	  }

	/* is this just a test for the length of the recieving buffer? */
	if(pData == NULL_PTR)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_OK; break;
	  }

	/* is the supplied buffer long enough? */
	if(*pulDataLen < ulEncryptedDataLen)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_BUFFER_TOO_SMALL; break;
	  }

	/* OK all set. lets compute */
	des_ede3_cbc_encrypt(pEncryptedData, 
			     pData, 
			     ulEncryptedDataLen, 
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[0], 
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[1], 
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[2], 
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->ivec, 
			     DES_DECRYPT);

	*pulDataLen=ulEncryptedDataLen;

	rv = CKR_OK;
	
      des3_cbc_err:
	if(session_data->decrypt_state != NULL_PTR)
	  CI_DES3_INFO_delete(session_data->decrypt_state);
	session_data->decrypt_state = NULL_PTR;
	
      }
      break;
      /* }}} */
      /* {{{ CKM_IDEA_ECB */
    case CKM_IDEA_ECB:
      {
	CK_ULONG count;
	rv = CKR_OK;

	CI_LogEntry("C_Decrypt", "IDEA ECB", rv , 0); 

	/* terminate operation */
	if(pulDataLen == NULL_PTR) 
	  {
	    rv = CKR_OK; goto idea_ecb_err;
	  }
	/* IDEA always takes multiples of 8 bytes */
	if(ulEncryptedDataLen%8 != 0)
	  {
	    rv = CKR_DATA_LEN_RANGE; goto idea_ecb_err;
	  }

	/* is this just a test for the length of the recieving buffer? */
	if(pData == NULL_PTR)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_OK; break;
	  }
	
	/* is the supplied buffer long enough? */
	if(*pulDataLen < ulEncryptedDataLen)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_BUFFER_TOO_SMALL; break;
	  }

	/* damit wir ne hoffnung haben */
	assert(sizeof(CK_BYTE) == sizeof(unsigned char));

	/* OK all set. lets compute */
	/* in blocks of 8 bytes. */
	for(count=0; count<ulEncryptedDataLen ; count+=8)
	  {
	    /* its the same function for decryption as well, only the key schedule differs */
	    idea_ecb_encrypt((unsigned char*)&(pEncryptedData[count]),
			     (unsigned char*)&(pData[count]), 
			     &(((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->sched));	    
	  }
	
	*pulDataLen=ulEncryptedDataLen;
	rv = CKR_OK;

      idea_ecb_err:

	if(session_data->decrypt_state!= NULL_PTR)
	  TC_free(session_data->decrypt_state);
	session_data->decrypt_state = NULL_PTR;

      }
      break;
      /* }}} */
      /* {{{ CKM_IDEA_CBC */
    case CKM_IDEA_CBC:
      {
	/* terminate operation */
	if(pulDataLen == NULL_PTR) 
	  {
	    rv = CKR_OK; goto idea_cbc_err;
	  }
	/* is the length of the supplied data a multiple of 8 to create des-blocks? */
	if(ulEncryptedDataLen%8 != 0)
	  {
	    rv = CKR_DATA_LEN_RANGE; goto idea_cbc_err;
	  }

	/* is this just a test for the length of the recieving buffer? */
	if(pData == NULL_PTR)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_OK; break;
	  }

	/* is the supplied buffer long enough? */
	if(*pulDataLen < ulEncryptedDataLen)
	  {
	    *pulDataLen = ulEncryptedDataLen;
	    rv = CKR_BUFFER_TOO_SMALL; break;
	  }

	/* OK all set. lets compute */
	idea_cbc_encrypt((unsigned char*)pEncryptedData, 
			 (unsigned char*)pData, 
			 ulEncryptedDataLen, 
			 &(((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->sched), 
			 ((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->ivec, 
			 IDEA_DECRYPT);

	*pulDataLen=ulEncryptedDataLen;
	rv = CKR_OK;

	if( ((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->ivec != NULL_PTR)
	  TC_free(((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->ivec);
    idea_cbc_err:
	if(session_data->decrypt_state)
	  TC_free(session_data->decrypt_state);
	session_data->decrypt_state = NULL_PTR;

      }
      break;
      /* }}} */
    default:
      rv = CKR_MECHANISM_INVALID;
      CI_VarLogEntry("C_Decrypt", "algorithm specified: %s", rv, 0, 
		     CI_MechanismStr(session_data->decrypt_mechanism));

    }

  CI_LogEntry("C_Decrypt", "...completed", rv , 0);

  return rv;
}
Ejemplo n.º 14
0
/* {{{ CI_Ceay_DecryptUpdate */
CK_DEFINE_FUNCTION(CK_RV, CI_Ceay_DecryptUpdate)(
  CK_I_SESSION_DATA_PTR  session_data,
  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
  CK_ULONG          ulEncryptedPartLen,  /* input length */
  CK_BYTE_PTR       pPart,               /* gets plaintext */
  CK_ULONG_PTR      pulPartLen           /* p-text size */
)
{
  CK_RV rv;

  switch(session_data->decrypt_mechanism)
    {
      /* {{{ CKM_RC4 */
    case CKM_RC4:
      {
	rv = CKR_OK;
	CI_LogEntry("C_DecryptUpdate", "RC4", rv , 0);    

	/* is this just a test for the length of the recieving buffer? */
	if(pPart == NULL_PTR)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_OK;
	  }
	
	/* is the supplied buffer long enough? */
	if(*pulPartLen < ulEncryptedPartLen)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_BUFFER_TOO_SMALL;
	  }
	
	/* OK all set. lets compute */
	RC4(session_data->decrypt_state,ulEncryptedPartLen,pEncryptedPart,pPart);
	
	*pulPartLen=ulEncryptedPartLen;
      }
      break;
      /* }}} */
      /* {{{ CKM_RC2_ECB */
    case CKM_RC2_ECB:
      {
	CK_ULONG count;

	rv = CKR_OK;
	CI_LogEntry("C_DecryptUpdate", "RC2 ECB", rv , 0);	  

	/* RC2 always takes multiples of 8 bytes */
	if(ulEncryptedPartLen%8 != 0)
	  return CKR_DATA_LEN_RANGE;

	/* is this just a test for the length of the recieving buffer? */
	if(pPart == NULL_PTR)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_OK;
	  }
	
	/* is the supplied buffer long enough? */
	if(*pulPartLen < ulEncryptedPartLen)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_BUFFER_TOO_SMALL;
	  }

	/* OK all set. lets compute */
	/* in blocks of 8 bytes. */
	for(count=0; count<ulEncryptedPartLen ; count+=8)
	  {
	    RC2_ecb_encrypt(&(pEncryptedPart[count]), &(pPart[count]), 
			    session_data->decrypt_state,
			    RC2_DECRYPT);	    
	  }
	
	*pulPartLen=ulEncryptedPartLen;

	rv = CKR_OK;
      }
      break;
      /* }}} */
      /* {{{ CKM_RC2_CBC */
    case CKM_RC2_CBC:
      {
	rv = CKR_OK;
	CI_LogEntry("C_DecryptUpdate", "RC2 CBC", rv , 0);	  

	/* is the length of the supplied data a multiple of 8 to create des-blocks? */
	if(ulEncryptedPartLen%8 != 0)
	  return CKR_DATA_LEN_RANGE;

	/* is this just a test for the length of the recieving buffer? */
	if(pPart == NULL_PTR)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_OK;
	  }

	/* is the supplied buffer long enough? */
	if(*pulPartLen < ulEncryptedPartLen)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_BUFFER_TOO_SMALL;
	  }

	/* OK all set. lets compute */
	RC2_cbc_encrypt((unsigned char*)pEncryptedPart, (unsigned char*)pPart, 
			 ulEncryptedPartLen, 
			 ((CK_I_CEAY_RC2_INFO_PTR)session_data->decrypt_state)->key, 
			 ((CK_I_CEAY_RC2_INFO_PTR)session_data->decrypt_state)->ivec, 
			 RC2_DECRYPT);
	
	*pulPartLen=ulEncryptedPartLen;

	rv = CKR_OK;
	
      }
      break;
      /* }}} */
      /* {{{ CKM_DES_ECB */
    case CKM_DES_ECB:
      {
	CK_ULONG count;

	rv = CKR_OK;
	CI_LogEntry("C_DecryptUpdate", "DES ECB", rv , 0);	  

	/* DES always takes multiples of 8 bytes */
	if(ulEncryptedPartLen%8 != 0)
	  return CKR_DATA_LEN_RANGE;

	/* is this just a test for the length of the recieving buffer? */
	if(pPart == NULL_PTR)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_OK;
	  }
	
	/* is the supplied buffer long enough? */
	if(*pulPartLen < ulEncryptedPartLen)
	{
	  *pulPartLen = ulEncryptedPartLen;
	  return CKR_BUFFER_TOO_SMALL;
	}

	/* OK all set. lets compute */
	/* in blocks of 8 bytes. */
	for(count=0; count<ulEncryptedPartLen ; count+=8)
	  {
	    des_ecb_encrypt((des_cblock*)(&(pEncryptedPart[count])),
			    (des_cblock*)(&(pPart[count])),
			    session_data->decrypt_state,
			    DES_DECRYPT);
	  }
	
	*pulPartLen=ulEncryptedPartLen;

	rv = CKR_OK;
      }
      break;
      /* }}} */
      /* {{{ CKM_DES_CBC */
    case CKM_DES_CBC:
      {
	rv = CKR_OK;
	CI_LogEntry("C_DecryptUpdate", "DES3 CBC", rv , 0);	  

	/* is the length of the supplied data a multiple of 8 to create des-blocks? */
	if(ulEncryptedPartLen%8 != 0)
	  return CKR_DATA_LEN_RANGE;

	/* is this just a test for the length of the recieving buffer? */
	if(pPart == NULL_PTR)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_OK;
	  }

	/* is the supplied buffer long enough? */
	if(*pulPartLen < ulEncryptedPartLen)
	{
	  *pulPartLen = ulEncryptedPartLen;
	  return CKR_BUFFER_TOO_SMALL;
	}

	/* OK all set. lets compute */
	des_ncbc_encrypt(pEncryptedPart, 
			 pPart, 
			 ulEncryptedPartLen, 
			 ((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->sched, 
			 &(((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->ivec), 
			 DES_DECRYPT);

	*pulPartLen=ulEncryptedPartLen;

	
	rv = CKR_OK;
	
      }
      break;
      /* }}} */
      /* {{{ CKM_DES_CBC_PAD */
    case CKM_DES_CBC_PAD:
      {
	CK_BYTE_PTR ptmpbuf = NULL_PTR;
	/* is the length of the supplied data a multiple of 8 to create des-blocks? */
	if(ulEncryptedPartLen%8 != 0)
	  return CKR_DATA_LEN_RANGE;

	/* is this just a test for the length of the recieving buffer? */
	if(pPart == NULL_PTR)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_OK;
	  }

	/* is the supplied buffer long enough? */
	if(*pulPartLen < ulEncryptedPartLen)
	{
	  *pulPartLen = ulEncryptedPartLen;
	  return CKR_BUFFER_TOO_SMALL;
	}

	/* OK all set. lets compute */
	ptmpbuf = CI_ByteStream_new(ulEncryptedPartLen);
	if(ptmpbuf == NULL_PTR) return CKR_HOST_MEMORY; 
	if(((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->pad)
	{
	  memcpy(ptmpbuf, ((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->lastblock, 8);
	  memcpy(ptmpbuf+8, pEncryptedPart, ulEncryptedPartLen-8);
	  *pulPartLen = ulEncryptedPartLen;
	}
	else
	{
	  memcpy(ptmpbuf, pEncryptedPart, ulEncryptedPartLen-8);
	  *pulPartLen = ulEncryptedPartLen-8;
	  ((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->pad = 8;
	}
	
	des_ncbc_encrypt(ptmpbuf, 
			 pPart, 
			 *pulPartLen, 
			 ((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->sched, 
			 &(((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->ivec), 
			 DES_DECRYPT);
	memcpy(((CK_I_CEAY_DES_INFO_PTR)session_data->decrypt_state)->lastblock, pEncryptedPart+ulEncryptedPartLen-8, 8);
	TC_free(ptmpbuf);

	rv = CKR_OK;
      }
    break;
      /* }}} */
      /* {{{ CKM_DES3_ECB */
    case CKM_DES3_ECB:
      {
	CK_ULONG count;

	/* DES always takes multiples of 8 bytes */
	if(ulEncryptedPartLen%8 != 0)
	  return CKR_DATA_LEN_RANGE;

	/* is this just a test for the length of the recieving buffer? */
	if(pPart == NULL_PTR)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_OK;
	  }
	
	/* is the supplied buffer long enough? */
	if(*pulPartLen < ulEncryptedPartLen)
	  {
	    *pulPartLen = ulEncryptedPartLen;	    
	    return CKR_BUFFER_TOO_SMALL;
	  }

	/* OK all set. lets compute */
	/* in blocks of 8 bytes. */
	for(count=0; count<ulEncryptedPartLen ; count+=8)
	  {
	    des_ecb3_encrypt((des_cblock*)(&(pPart[count])),
			     (des_cblock*)(&(pEncryptedPart[count])), 
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[0],
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[1],
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[2],
			     DES_DECRYPT);
	  }
	
	*pulPartLen=ulEncryptedPartLen;

	rv = CKR_OK;
      }
      break;
      /* }}} */
      /* {{{ CKM_DES3_CBC */
    case CKM_DES3_CBC:
      {
	
	rv = CKR_OK;
	CI_LogEntry("C_DecryptUpdate", "IDEA CBC", rv , 0);	  

	/* is the length of the supplied data a multiple of 8 to create des-blocks? */
	if(ulEncryptedPartLen%8 != 0)
	  return CKR_DATA_LEN_RANGE;

	/* is this just a test for the length of the recieving buffer? */
	if(pPart == NULL_PTR)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_OK;
	  }

	/* is the supplied buffer long enough? */
	if(*pulPartLen < ulEncryptedPartLen)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_BUFFER_TOO_SMALL;
	  }


	/* OK all set. lets compute */
	des_ede3_cbc_encrypt(pEncryptedPart, 
			     pPart, 
			     ulEncryptedPartLen, 
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[0], 
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[1], 
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->sched[2], 
			     ((CK_I_CEAY_DES3_INFO_PTR)session_data->decrypt_state)->ivec, 
			     DES_DECRYPT);

	*pulPartLen=ulEncryptedPartLen;

	rv = CKR_OK;	
      }
      break;
      /* }}} */
      /* {{{ CKM_IDEA_ECB */
    case CKM_IDEA_ECB:
      {
	CK_ULONG count;

	rv = CKR_OK;
	CI_LogEntry("C_DecryptUpdate", "IDEA ECB", rv , 0);	  

	/* DES always takes multiples of 8 bytes */
	if(ulEncryptedPartLen%8 != 0)
	  return CKR_DATA_LEN_RANGE;

	/* is this just a test for the length of the recieving buffer? */
	if(pPart == NULL_PTR)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_OK;
	  }
	
	/* is the supplied buffer long enough? */
	if(*pulPartLen < ulEncryptedPartLen)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_BUFFER_TOO_SMALL;
	  }

	/* damit wir ne hoffnung haben */
	assert(sizeof(CK_BYTE) == sizeof(unsigned char));

	/* OK all set. lets compute */
	/* in blocks of 8 bytes. */
	for(count=0; count<ulEncryptedPartLen ; count+=8)
	  {
	    /* its the same function for decryption as well, only the key schedule differs */
	    idea_ecb_encrypt((unsigned char*)&(pEncryptedPart[count]),
			     (unsigned char*)&(pPart[count]),
			     &(((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->sched));	    
	  }
	
	*pulPartLen=ulEncryptedPartLen;

	rv = CKR_OK;
      }
      break;
      /* }}} */
      /* {{{ CKM_IDEA_CBC */
    case CKM_IDEA_CBC:
      {
	rv = CKR_OK;
	CI_LogEntry("C_DecryptUpdate", "IDEA CBC", rv , 0);	  

	/* is the length of the supplied data a multiple of 8 to create des-blocks? */
	if(ulEncryptedPartLen%8 != 0)
	  return CKR_DATA_LEN_RANGE;

	/* is this just a test for the length of the recieving buffer? */
	if(pPart == NULL_PTR)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_OK;
	  }

	/* is the supplied buffer long enough? */
	if(*pulPartLen < ulEncryptedPartLen)
	  {
	    *pulPartLen = ulEncryptedPartLen;
	    return CKR_BUFFER_TOO_SMALL;
	  }

	/* OK all set. lets compute */
	idea_cbc_encrypt((unsigned char*)pEncryptedPart, 
			 (unsigned char*)pPart, 
			 ulEncryptedPartLen, 
			 &(((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->sched), 
			 ((CK_I_CEAY_IDEA_INFO_PTR)session_data->decrypt_state)->ivec, 
			 IDEA_DECRYPT);

	*pulPartLen=ulEncryptedPartLen;

	rv = CKR_OK;
      }
      break;
      /* }}} */
    default:
      rv = CKR_MECHANISM_INVALID;
      CI_VarLogEntry("C_DecryptUpdate", "algorithm specified: %s", rv, 0, 
		     CI_MechanismStr(session_data->decrypt_mechanism));
    }
  
  CI_VarLogEntry("C_DecryptUpdate", "decryption (%s) result: %s", rv, 2,
		 CI_MechanismStr(session_data->decrypt_mechanism),
		 CI_PrintableByteStream(pPart,*pulPartLen));

  CI_LogEntry("C_DecryptUpdate", "...completed", rv , 0);	  

  return rv;
}