예제 #1
0
파일: aes.c 프로젝트: 3sOx/asuswrt-merlin
/* AES-CBC mode decryption algorithm
 *	- handle partial plaintext blocks with padding
 *	- ptxt and ctxt can point to the same location
 *	- returns -1 on error
 */
int
BCMROMFN(aes_cbc_decrypt_pad)(uint32 *rk,
                          const size_t key_len,
                          const uint8 *nonce,
                          const size_t data_len,
                          const uint8 *ctxt,
                          uint8 *ptxt,
                          uint8 padd_type)
{
	uint8 tmp[AES_BLOCK_SZ];
	uint32 remaining = (uint32)data_len;
	/* First block get XORed with nonce/IV */
	const unsigned char *iv = nonce;
	const unsigned char *crypt_data = ctxt;
	uint32 plaintext_len = 0;
	unsigned char *plain_data = ptxt;

	if (data_len % AES_BLOCK_SZ)
		return (-1);
	if (data_len < AES_BLOCK_SZ)
		return (-1);

	while (remaining >= AES_BLOCK_SZ) {
		aes_block_decrypt((int)AES_ROUNDS(key_len), rk, crypt_data, tmp);
		xor_128bit_block(tmp, iv, plain_data);
		remaining -= AES_BLOCK_SZ;
		iv = crypt_data;
		crypt_data += AES_BLOCK_SZ;
		plain_data += AES_BLOCK_SZ;
		plaintext_len += AES_BLOCK_SZ;
	}
	if (padd_type == PAD_LEN_PADDING)
		plaintext_len -= ptxt[plaintext_len -1];
	return (plaintext_len);
}
예제 #2
0
bool dec_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(!aes_block_decrypt(buffer,total_len)) {
        return false;
    }

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

    return true;
}
예제 #3
0
/* aes_unwrap: perform AES-based key unwrap function defined in RFC3394,
 *	return 0 on success, 1 on error
 *	input is il bytes
 *	output is (il-8) bytes
 */
int
BCMROMFN(aes_unwrap)(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 + AKW_BLOCK_LEN];
	uint8 B[AES_BLOCK_SZ];
	size_t ol = il - AKW_BLOCK_LEN;
	int n = (int)(ol/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 + AKW_BLOCK_LEN)) {
		dbg(("aes_unwrap: input length %lu too large\n", (unsigned long)il));
		return (1);
	}
	if (il % AKW_BLOCK_LEN) {
		dbg(("aes_unwrap: 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   Data:       "));
	for (k = 0; k < (int)il; k++)
		dbg(("%02X", input[k]));
	dbg(("\n\n   Unwrap: \n"));

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

	/* Set A = C[0] */
	memcpy(A, input, AKW_BLOCK_LEN);

	/* For i = 1 to n */
	/*	R[i] = C[i] */
	memcpy(R, &input[AKW_BLOCK_LEN], ol);

	/* For j = 5 to 0 */
	for (j = 5; j >= 0; j--) {
		/* For i = n to 1 */
		for (i = n - 1; i >= 0; i--) {
			dbg(("\n   %d\n", (n*j)+i+1));
			pinter("   In   ", A, ol, R);

			/* B = AES - 1 (K, (A ^ t) | R[i]) where t = n * j + i */
			A[AKW_BLOCK_LEN - 1] ^= ((n*j)+i+1);
			pinter("   XorT ", A, ol, R);

			memcpy(&A[AKW_BLOCK_LEN], &R[i*AKW_BLOCK_LEN], AKW_BLOCK_LEN);
			aes_block_decrypt((int)AES_ROUNDS(kl), rk, A, B);

			/* A = MSB(64, B) */
			memcpy(&A[0], &B[0], AKW_BLOCK_LEN);

			/* R[i] = LSB(64, B) */
			memcpy(&R[i*AKW_BLOCK_LEN], &B[AKW_BLOCK_LEN], AKW_BLOCK_LEN);
			pinter("   Dec  ", A, ol, R);
		}
	}
	if (!memcmp(A, aeskeywrapIV, AKW_BLOCK_LEN)) {
		/* For i = 1 to n */
		/*	P[i] = R[i] */
		memcpy(&output[0], R, ol);
		return 0;
	} else {
		dbg(("aes_unwrap: IV mismatch in unwrapped data\n"));
		return 1;
	}
}