Пример #1
0
/* AES-CTR mode encryption/decryption algorithm
 *	- max data_len is (AES_BLOCK_SZ * 2^16)
 *	- nonce must be AES_BLOCK_SZ bytes
 *	- assumes nonce is ready to use as-is (i.e. any
 *		encryption/randomization of nonce/IV is handled by the caller)
 *	- ptxt and ctxt can point to the same location
 *	- returns -1 on error
 */
int
BCMROMFN(aes_ctr_crypt)(unsigned int *rk,
                        const size_t key_len,
                        const uint8 *nonce,
                        const size_t data_len,
                        const uint8 *ptxt,
                        uint8 *ctxt)
{
	size_t k;
	uint8 tmp[AES_BLOCK_SZ], ctr[AES_BLOCK_SZ];

	if (data_len > (AES_BLOCK_SZ * AES_CTR_MAXBLOCKS)) return (-1);

	memcpy(ctr, nonce, AES_BLOCK_SZ);

	for (k = 0; k < (data_len / AES_BLOCK_SZ); k++) {
		aes_block_encrypt((int)AES_ROUNDS(key_len), rk, ctr, tmp);
		xor_128bit_block(ptxt, tmp, ctxt);
		ctr[AES_BLOCK_SZ-1]++;
		if (!ctr[AES_BLOCK_SZ - 1]) ctr[AES_BLOCK_SZ - 2]++;
		ptxt += AES_BLOCK_SZ;
		ctxt += AES_BLOCK_SZ;
	}
	/* handle partial block */
	if (data_len % AES_BLOCK_SZ) {
		aes_block_encrypt((int)AES_ROUNDS(key_len), rk, ctr, tmp);
		for (k = 0; k < (data_len % AES_BLOCK_SZ); k++)
			ctxt[k] = ptxt[k] ^ tmp[k];
	}

	return (0);
}
Пример #2
0
int
BCMROMFN(aes_cbc_encrypt_pad)(uint32 *rk,
                          const size_t key_len,
                          const uint8 *nonce,
                          const size_t data_len,
                          const uint8 *ptxt,
                          uint8 *ctxt,
                          uint8 padd_type)
{

	uint8 tmp[AES_BLOCK_SZ];
	uint32 encrypt_len = 0;
	uint32 j;

	/* First block get XORed with nonce/IV */
	const unsigned char *iv = nonce;
	unsigned char *crypt_data = ctxt;
	const unsigned char *plain_data = ptxt;
	uint32 remaining = (uint32)data_len;

	while (remaining >= AES_BLOCK_SZ) {
		xor_128bit_block(iv, plain_data, tmp);
		aes_block_encrypt((int)AES_ROUNDS(key_len), rk, tmp, crypt_data);
		remaining -= AES_BLOCK_SZ;
		iv = crypt_data;
		crypt_data += AES_BLOCK_SZ;
		plain_data += AES_BLOCK_SZ;
		encrypt_len += AES_BLOCK_SZ;
	}

	if (padd_type == NO_PADDING)
		return encrypt_len;

	if (remaining) {
		for (j = 0; j < remaining; j++) {
			tmp[j] = plain_data[j] ^ iv[j];
		}
	}
	switch (padd_type) {
	case PAD_LEN_PADDING:
		for (j = remaining; j < AES_BLOCK_SZ; j++) {
			tmp[j] = (AES_BLOCK_SZ - remaining) ^  iv[j];
		}
		break;
	default:
		return -1;
	}

	aes_block_encrypt((int)AES_ROUNDS(key_len), rk, tmp, crypt_data);
	encrypt_len += AES_BLOCK_SZ;

	return (encrypt_len);
}
Пример #3
0
bool enc_buffer(void * buffer, size_t real_len, size_t total_len, int cipher_num)
{
    if(real_len > total_len || buffer == NULL)
        return false;

    if(total_len % 16 != 0)
        return false;

    if(!xor_fibonacci_crypt(buffer, real_len, cipher_num)) {
        return false;
    }

    if(!aes_block_encrypt(buffer,total_len)) {
        return false;
    }
    
    return true;
}
Пример #4
0
int
BCMROMFN(aes_ccm_mac)(unsigned int *rk,
                      const size_t key_len,
                      const uint8 *nonce,
                      const size_t aad_len,
                      const uint8 *aad,
                      const size_t data_len,
                      const uint8 *ptxt,
                      uint8 *mac)
{
	uint8 B_0[AES_BLOCK_SZ], X[AES_BLOCK_SZ];
	size_t j, k;

	if (aad_len > AES_CCM_AAD_MAX_LEN) return (-1);

	pres("aes_ccm_mac: nonce:", AES_CCM_NONCE_LEN, nonce);
	pres("aes_ccm_mac: aad:", aad_len, aad);
	pres("aes_ccm_mac: input:", data_len, ptxt);

	/* B_0 = Flags || Nonce || l(m) */
	B_0[0] = AES_CCM_AUTH_FLAGS;
	if (aad_len)
		B_0[0] |= AES_CCM_AUTH_AAD_FLAG;
	memcpy(&B_0[1], nonce, AES_CCM_NONCE_LEN);
	B_0[AES_BLOCK_SZ - 2] = (uint8)(data_len >> 8) & 0xff;
	B_0[AES_BLOCK_SZ - 1] = (uint8)(data_len & 0xff);

	/* X_1 := E( K, B_0 ) */
	pres("aes_ccm_mac: CBC IV in:", AES_BLOCK_SZ, B_0);
	aes_block_encrypt((int)AES_ROUNDS(key_len), rk, B_0, X);
	pres("aes_ccm_mac: CBC IV out:", AES_BLOCK_SZ, X);

	/* X_i + 1 := E( K, X_i XOR B_i )  for i = 1, ..., n */

	/* first the AAD */
	if (aad_len) {
		pres("aes_ccm_mac: aad:", aad_len, aad);
		X[0] ^= (aad_len >> 8) & 0xff;
		X[1] ^= aad_len & 0xff;
		k = 2;
		j = aad_len;
		while (j--) {
			X[k] ^= *aad++;
			k++;
			if (k == AES_BLOCK_SZ) {
				pres("aes_ccm_mac: After xor (full block aad):", AES_BLOCK_SZ, X);
				aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
				pres("aes_ccm_mac: After AES (full block aad):", AES_BLOCK_SZ, X);
				k = 0;
			}
		}
		/* handle partial last block */
		if (k % AES_BLOCK_SZ) {
			pres("aes_ccm_mac: After xor (partial block aad):", AES_BLOCK_SZ, X);
			aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
			pres("aes_ccm_mac: After AES (partial block aad):", AES_BLOCK_SZ, X);
		}
	}

	/* then the message data */
	for (k = 0; k < (data_len / AES_BLOCK_SZ); k++) {
		xor_128bit_block(X, ptxt, X);
		pres("aes_ccm_mac: After xor (full block data):", AES_BLOCK_SZ, X);
		ptxt += AES_BLOCK_SZ;
		aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
		pres("aes_ccm_mac: After AES (full block data):", AES_BLOCK_SZ, X);
	}
	/* last block may be partial, padding is implicit in this xor */
	for (k = 0; k < (data_len % AES_BLOCK_SZ); k++)
		X[k] ^= *ptxt++;
	if (data_len % AES_BLOCK_SZ) {
		pres("aes_ccm_mac: After xor (final block data):", AES_BLOCK_SZ, X);
		aes_block_encrypt((int)AES_ROUNDS(key_len), rk, X, X);
		pres("aes_ccm_mac: After AES (final block data):", AES_BLOCK_SZ, X);
	}

	/* T := first-M-bytes( X_n+1 ) */
	memcpy(mac, X, AES_CCM_AUTH_LEN);
	pres("aes_ccm_mac: MAC:", AES_CCM_AUTH_LEN, mac);

	return (0);
}
Пример #5
0
/* aes_wrap: perform AES-based keywrap function defined in RFC3394
 *	return 0 on success, 1 on error
 *	input is il bytes
 *	output is (il+8) bytes
 */
int
BCMROMFN(aes_wrap)(size_t kl, uint8 *key, size_t il, uint8 *input, uint8 *output)
{
	uint32 rk[4*(AES_MAXROUNDS+1)];
	uint8 A[AES_BLOCK_SZ];
	uint8 R[AKW_MAX_WRAP_LEN];
	uint8 B[AES_BLOCK_SZ];
	int n = (int)(il/AKW_BLOCK_LEN), i, j, k;

	/* validate kl (must be valid AES key length)  */
	if ((kl != 16) && (kl != 24) && (kl != 32)) {
		dbg(("aes_wrap: invlaid key length %lu\n", (unsigned long)kl));
		return (1);
	}
	if (il > AKW_MAX_WRAP_LEN) {
		dbg(("aes_wrap: input length %lu too large\n", (unsigned long)il));
		return (1);
	}
	if (il % AKW_BLOCK_LEN) {
		dbg(("aes_wrap: input length %lu must be a multiple of block length\n",
		     (unsigned long)il));
		return (1);
	}

	dbg(("   Input:\n"));
	dbg(("   KEK:        "));
	for (k = 0; k < (int)kl; k++)
		dbg(("%02X", key[k]));
	dbg(("\n   Key Data:   "));
	for (k = 0; k < (int)il; k++)
		dbg(("%02X", input[k]));
	dbg(("\n\n   Wrap: \n"));

	rijndaelKeySetupEnc(rk, key, (int)AES_KEY_BITLEN(kl));

	/* Set A = IV */
	memcpy(A, aeskeywrapIV, AKW_BLOCK_LEN);
	/* For i = 1 to n */
	/*	R[i] = P[i] */
	memcpy(R, input, il);

	/* For j = 0 to 5 */
	for (j = 0; j < 6; j++) {
		/* For i = 1 to n */
		for (i = 0; i < n; i++) {
			dbg(("\n   %d\n", (n*j)+i+1));
			pinter("   In   ", A, il, R);
			/* B = AES(K, A | R[i]) */
			memcpy(&A[AKW_BLOCK_LEN], &R[i*AKW_BLOCK_LEN], AKW_BLOCK_LEN);
			aes_block_encrypt((int)AES_ROUNDS(kl), rk, A, B);

			/* R[i] = LSB(64, B) */
			memcpy(&R[i*AKW_BLOCK_LEN], &B[AKW_BLOCK_LEN], AKW_BLOCK_LEN);

			/* A = MSB(64, B) ^ t where t = (n*j)+i */
			memcpy(&A[0], &B[0], AKW_BLOCK_LEN);
			pinter("   Enc  ", A, il, R);
			A[AKW_BLOCK_LEN-1] ^= ((n*j)+i+1);
			pinter("   XorT ", A, il, R);
		}
	}
	/* Set C[0] = A */
	memcpy(output, A, AKW_BLOCK_LEN);
	/* For i = 1 to n */
	/* 	C[i] = R[i] */
	memcpy(&output[AKW_BLOCK_LEN], R, il);

	return (0);
}