Beispiel #1
0
/* does one encryption or decryption in ECB mode and compare result */
int ccmode_ecb_test_one(const struct ccmode_ecb *ecb, size_t keylen, const void *keydata,
                        unsigned long nblocks, const void *in, const void *out)
{
    unsigned char temp[nblocks*ecb->block_size];
    ccecb_ctx_decl(ecb->size, key);
    ecb->init(ecb, key, keylen, keydata);
    ecb->ecb(key, nblocks, in, temp);

#ifdef _INTERNAL_DEBUG_
    {
        char k[keylen*2+1];
        char i[ecb->block_size*nblocks*2+1];
        char o[ecb->block_size*nblocks*2+1];
        char t[ecb->block_size*nblocks*2+1];

        cc_bin2hex(keylen, k, keydata);
        cc_bin2hex(ecb->block_size*nblocks, i, in);
        cc_bin2hex(ecb->block_size*nblocks, o, out);
        cc_bin2hex(ecb->block_size*nblocks, t, temp);

        fprintf(stderr, "k: %s, i: %s, o:%s, t:%s\n", k, i, o, t);
    }
#endif

    return memcmp(out, temp, ecb->block_size*nblocks);
}
Beispiel #2
0
void CCAESCmac(const void *key,
               const uint8_t *data,
               size_t dataLength,			/* length of data in bytes */
               void *macOut)				/* MAC written here */
{
    uint8_t       X[16],Y[16], M_last[16], padded[16];
    uint8_t       K1[16], K2[16];
    int         flag;
    size_t      n;
    const struct ccmode_ecb *aesmode = getCipherMode(kCCAlgorithmAES128, kCCModeECB, kCCEncrypt).ecb;
    ccecb_ctx_decl(aesmode->size, ctx);

    CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n");

	// CMacInit
    
    aesmode->init(aesmode, ctx, 16, key);
    aesmode->ecb(ctx, 1, Y, X);
    ccGenAESSubKey(aesmode, ctx, K1, K2);
    
    // CMacUpdates (all in this case)
    
    n = (dataLength+15) / 16;       /* n is number of rounds */
    
    if ( 0 == n ) {
        n = 1;
        flag = 0;
    } else {
        if ( (dataLength%16) == 0 ) flag = 1;
        else  flag = 0;
    }
    
    if ( flag ) { /* last block is complete block */
        xor_128(&data[16*(n-1)],K1,M_last);
    } else {
        ccAESCMacPadding(&data[16*(n-1)],padded,dataLength%16);
        xor_128(padded,K2,M_last);
    }
    
    memset(X, 0, 16);
    for (size_t i=0; i<n-1; i++ ) {
        xor_128(X,&data[16*i],Y); /* Y := Mi (+) X  */
        aesmode->ecb(ctx, 1, Y, X);
    }
    
    // CMacFinal
    
    xor_128(X,M_last,Y);
    aesmode->ecb(ctx, 1, Y, X);
    
    memcpy(macOut, X, 16);
}
Beispiel #3
0
/* Initialize a block of 'nblocks' of zeroes,
 Does 'loops' consecutive encryption (ECB) in place,
 then 'loops' decryption (ECB) in place,
 result should be zeroes. */
int ccmode_ecb_test_key_self(const struct ccmode_ecb *encrypt, const struct ccmode_ecb *decrypt, unsigned long nblocks,
                             size_t keylen, const void *keydata, unsigned long loops)
{
    unsigned char temp[nblocks*encrypt->block_size];
    unsigned char zeroes[nblocks*encrypt->block_size];
    ccecb_ctx_decl(decrypt->size, dkey);
    ccecb_ctx_decl(encrypt->size, ekey);

    cc_zero(nblocks*encrypt->block_size,temp);
    cc_zero(nblocks*encrypt->block_size,zeroes);

    encrypt->init(encrypt, ekey, keylen, keydata);
    decrypt->init(decrypt, dkey, keylen, keydata);

    for (unsigned long i=0; i<loops; i++)
        encrypt->ecb(ekey, nblocks, temp, temp);

    for (unsigned long i=0; i<loops; i++)
        decrypt->ecb(dkey, nblocks, temp, temp);

    return memcmp(zeroes, temp, encrypt->block_size*nblocks);
}
Beispiel #4
0
static double perf_ccecb_init(unsigned long loops, unsigned long size CC_UNUSED, const void *arg)
{
    const struct ccecb_perf_test *test=arg;
    const struct ccmode_ecb *ecb=test->ecb;
    size_t keylen=test->keylen;

    unsigned char keyd[keylen];
    cc_zero(keylen,keyd);
    ccecb_ctx_decl(ecb->size, key);

    perf_start();
    while(loops--)
        ccecb_init(ecb, key, keylen, keyd);
    return perf_time();
}
Beispiel #5
0
static double perf_ccecb_update(unsigned long loops, unsigned long size, const void *arg)
{
    const struct ccecb_perf_test *test=arg;
    const struct ccmode_ecb *ecb=test->ecb;
    size_t keylen=test->keylen;
    unsigned long nblocks=size/ecb->block_size;

    unsigned char keyd[keylen];
    unsigned char temp[nblocks*ecb->block_size];

    cc_zero(keylen,keyd);
    ccecb_ctx_decl(ecb->size, key);
    ccecb_init(ecb, key, keylen, keyd);

    perf_start();
    while(loops--)
        ccecb_update(ecb,key, nblocks, temp, temp);
    return perf_time();
}
Beispiel #6
0
static int
df(struct ccdrbg_nistctr_state *drbg, const char *input_string[], uint32_t L[],
    uint32_t input_string_count, uint8_t *output_string, unsigned long N)
{
	unsigned long   j, k, blocks;
    uint64_t        sum_L;
	uint32_t		*temp;
	uint32_t		*X;
	uint32_t		buffer[CCADRBG_TEMPLEN_INTS(drbg)];
    /* declare a key */
    ccecb_ctx_decl(drbg->ecb->size, key);

	/*
	 * NIST SP 800-90 March 2007 10.4.2 states that 512 bits is
	 * the maximum length for the approved block cipher algorithms.
     *
     * Also states that L(sum_L) and N are 32 bits integers.
	 */
    cc_assert(drbg->ecb->block_size<=512/8);
	uint32_t output_buffer[512 / 8 / sizeof(uint32_t)];

	if (N > sizeof(output_buffer) || N < 1)
	{
		ccecb_ctx_clear(drbg->ecb->size, key);
		return -1;
	}
		

	sum_L = 0;
	for (j = 0; j < input_string_count; ++j)
		sum_L += L[j];
    //sum_L is the sum of the all input data-lengths. Since maximum parameters lengths are set properly
    //in the header file, sum_L cannot be more than 32 bits. But a change to those parameters by
    //someone who is not aware of this summation here, would be a disaster.
    //Therefore, we make sum_L 64 bits and we perform the test here.
    if(sum_L > 0xFFFFffff)
        return -1;

	/* [6] temp = Null string */
	temp = buffer;

	/* [9] while len(temp) < keylen + outlen, do */
	for (j = 0; j < CCADRBG_TEMPLEN_BLOCKS(drbg); ++j)
	{
		/* [9.2] temp = temp || BCC(K, (IV || S)) */

		/* Since we have precomputed BCC(K, IV), we start with that... */
		memcpy(&temp[0], &drbg->encryptedIV[j*CCADRBG_OUTLEN(drbg)+0], CCADRBG_OUTLEN(drbg));

        /* typecast: ok, checks above */
		bcc_init(drbg, (uint32_t)sum_L, (uint32_t)N, temp);

		/* Compute the rest of BCC(K, (IV || S)) */
		for (k = 0; k < input_string_count; ++k)
			df_bcc_update(drbg, input_string[k], L[k], temp);

		df_bcc_final(drbg, temp);

		temp += CCADRBG_OUTLEN_INTS(drbg);
	}

	/* [6] temp = Null string */
	temp = buffer;

	/* [10] K = Leftmost keylen bits of temp */
    drbg->ecb->init(drbg->ecb, key, CCADRBG_KEYLEN(drbg), &temp[0]);

	/* [11] X = next outlen bits of temp */
	X = &temp[CCADRBG_KEYLEN_INTS(drbg)];

	/* [12] temp = Null string */
	temp = output_buffer;

	/* [13] While len(temp) < number_of_bits_to_return, do */
	blocks = (N / CCADRBG_OUTLEN(drbg));
	if (N & (CCADRBG_OUTLEN(drbg) - 1))
		++blocks;
	for (j = 0; j < blocks; ++j)
	{
		/* [13.1] X = Block_Encrypt(K, X) */
        drbg->ecb->ecb(key, 1, X, temp);
		X = temp;
		temp += CCADRBG_OUTLEN_INTS(drbg);
	}

	/* [14] requested_bits = Leftmost number_of_bits_to_return of temp */
	memcpy(output_string, output_buffer, N);
	ccecb_ctx_clear(drbg->ecb->size, key);
	cc_clear(sizeof(buffer), buffer);
	cc_clear(sizeof(output_buffer), output_buffer);

	return 0;
}