⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aes_core.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 5 页
字号:
            break;
        }

        s0 =
            Td0[(t0 >> 24)       ] ^
            Td1[(t3 >> 16) & 0xff] ^
            Td2[(t2 >>  8) & 0xff] ^
            Td3[(t1      ) & 0xff] ^
            rk[0];
        s1 =
            Td0[(t1 >> 24)       ] ^
            Td1[(t0 >> 16) & 0xff] ^
            Td2[(t3 >>  8) & 0xff] ^
            Td3[(t2      ) & 0xff] ^
            rk[1];
        s2 =
            Td0[(t2 >> 24)       ] ^
            Td1[(t1 >> 16) & 0xff] ^
            Td2[(t0 >>  8) & 0xff] ^
            Td3[(t3      ) & 0xff] ^
            rk[2];
        s3 =
            Td0[(t3 >> 24)       ] ^
            Td1[(t2 >> 16) & 0xff] ^
            Td2[(t1 >>  8) & 0xff] ^
            Td3[(t0      ) & 0xff] ^
            rk[3];
    }
#endif /* ?FULL_UNROLL */
    /*
	 * apply last round and
	 * map cipher state to byte array block:
	 */
   	s0 =
   		(Td4[(t0 >> 24)       ] & 0xff000000) ^
   		(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
   		(Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
   		(Td4[(t1      ) & 0xff] & 0x000000ff) ^
   		rk[0];
	PUTU32(out     , s0);
   	s1 =
   		(Td4[(t1 >> 24)       ] & 0xff000000) ^
   		(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
   		(Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
   		(Td4[(t2      ) & 0xff] & 0x000000ff) ^
   		rk[1];
	PUTU32(out +  4, s1);
   	s2 =
   		(Td4[(t2 >> 24)       ] & 0xff000000) ^
   		(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
   		(Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
   		(Td4[(t3      ) & 0xff] & 0x000000ff) ^
   		rk[2];
	PUTU32(out +  8, s2);
   	s3 =
   		(Td4[(t3 >> 24)       ] & 0xff000000) ^
   		(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
   		(Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
   		(Td4[(t0      ) & 0xff] & 0x000000ff) ^
   		rk[3];
	PUTU32(out + 12, s3);
}

void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
		     const unsigned long length, const AES_KEY *key,
		     unsigned char *ivec, const int enc) {

	unsigned long n;
	unsigned long len = length;
	unsigned char tmp[AES_BLOCK_SIZE];

	assert(in && out && key && ivec);
	assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));

	if (AES_ENCRYPT == enc) {
		while (len >= AES_BLOCK_SIZE) {
			for(n=0; n < AES_BLOCK_SIZE; ++n)
				tmp[n] = in[n] ^ ivec[n];
			AES_encrypt(tmp, out, key);
			memcpy(ivec, out, AES_BLOCK_SIZE);
			len -= AES_BLOCK_SIZE;
			in += AES_BLOCK_SIZE;
			out += AES_BLOCK_SIZE;
		}
		if (len) {
			for(n=0; n < len; ++n)
				tmp[n] = in[n] ^ ivec[n];
			for(n=len; n < AES_BLOCK_SIZE; ++n)
				tmp[n] = ivec[n];
			AES_encrypt(tmp, tmp, key);
			memcpy(out, tmp, AES_BLOCK_SIZE);
			memcpy(ivec, tmp, AES_BLOCK_SIZE);
		}			
	} else {
		while (len >= AES_BLOCK_SIZE) {
			memcpy(tmp, in, AES_BLOCK_SIZE);
			AES_decrypt(in, out, key);
			for(n=0; n < AES_BLOCK_SIZE; ++n)
				out[n] ^= ivec[n];
			memcpy(ivec, tmp, AES_BLOCK_SIZE);
			len -= AES_BLOCK_SIZE;
			in += AES_BLOCK_SIZE;
			out += AES_BLOCK_SIZE;
		}
		if (len) {
			memcpy(tmp, in, AES_BLOCK_SIZE);
			AES_decrypt(tmp, tmp, key);
			for(n=0; n < len; ++n)
				out[n] ^= ivec[n];
			memcpy(ivec, tmp, AES_BLOCK_SIZE);
		}			
	}
}

void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
	const unsigned long length, const AES_KEY *key,
	unsigned char *ivec, int *num, const int enc) {

	unsigned int n;
	unsigned long l = length;
	unsigned char c;

	assert(in && out && key && ivec && num);

	n = *num;

	if (enc) {
		while (l--) {
			if (n == 0) {
				AES_encrypt(ivec, ivec, key);
			}
			ivec[n] = *(out++) = *(in++) ^ ivec[n];
			n = (n+1) % AES_BLOCK_SIZE;
		}
	} else {
		while (l--) {
			if (n == 0) {
				AES_encrypt(ivec, ivec, key);
			}
			c = *(in);
			*(out++) = *(in++) ^ ivec[n];
			ivec[n] = c;
			n = (n+1) % AES_BLOCK_SIZE;
		}
	}

	*num=n;
}

/* increment counter (128-bit int) by 1 */
static void AES_ctr128_inc(unsigned char *counter) {
	unsigned long c;

	/* Grab bottom dword of counter and increment */
#ifdef L_ENDIAN
	c = GETU32(counter +  0);
	c++;
	PUTU32(counter +  0, c);
#else
	c = GETU32(counter + 12);
	c++;
	PUTU32(counter + 12, c);
#endif

	/* if no overflow, we're done */
	if (c)
		return;

	/* Grab 1st dword of counter and increment */
#ifdef L_ENDIAN
	c = GETU32(counter +  4);
	c++;
	PUTU32(counter +  4, c);
#else
	c = GETU32(counter +  8);
	c++;
	PUTU32(counter +  8, c);
#endif

	/* if no overflow, we're done */
	if (c)
		return;

	/* Grab 2nd dword of counter and increment */
#ifdef L_ENDIAN
	c = GETU32(counter +  8);
	c++;
	PUTU32(counter +  8, c);
#else
	c = GETU32(counter +  4);
	c++;
	PUTU32(counter +  4, c);
#endif

	/* if no overflow, we're done */
	if (c)
		return;

	/* Grab top dword of counter and increment */
#ifdef L_ENDIAN
	c = GETU32(counter + 12);
	c++;
	PUTU32(counter + 12, c);
#else
	c = GETU32(counter +  0);
	c++;
	PUTU32(counter +  0, c);
#endif

}

void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
	const unsigned long length, const AES_KEY *key,
	unsigned char ivec[AES_BLOCK_SIZE],
	unsigned char ecount_buf[AES_BLOCK_SIZE],
	unsigned int *num) {

	unsigned int n;
	unsigned long l=length;

//	assert(in && out && key && counter && num);
	assert(in && out && key && num);
	assert(*num < AES_BLOCK_SIZE);

	n = *num;

	while (l--) {
		if (n == 0) {
			AES_encrypt(ivec, ecount_buf, key);
 			AES_ctr128_inc(ivec);
		}
		*(out++) = *(in++) ^ ecount_buf[n];
		n = (n+1) % AES_BLOCK_SIZE;
	}

	*num=n;
}

void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
		     const AES_KEY *key, const int enc) {

        assert(in && out && key);
	assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));

	if (AES_ENCRYPT == enc)
		AES_encrypt(in, out, key);
	else
		AES_decrypt(in, out, key);
}

const char *AES_version="AES";

const char *AES_options(void) {
#ifdef FULL_UNROLL
        return "aes(full)";
#else   
        return "aes(partial)";
#endif
}

void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
	const unsigned long length, const AES_KEY *key,
	unsigned char *ivec, int *num) {

	unsigned int n;
	unsigned long l=length;

	assert(in && out && key && ivec && num);

	n = *num;

	while (l--) {
		if (n == 0) {
			AES_encrypt(ivec, ivec, key);
		}
		*(out++) = *(in++) ^ ivec[n];
		n = (n+1) % AES_BLOCK_SIZE;
	}

	*num=n;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -