xref: /OK3568_Linux_fs/external/security/librkcrypto/test/c_mode/aes_cts.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 #include "aes_core.h"
6 
rk_crypto_cbc128_encrypt(const unsigned char * in,unsigned char * out,int len,const void * key,unsigned char * ivec)7 static void rk_crypto_cbc128_encrypt(const unsigned char *in, unsigned char *out,
8 		 int len, const void *key, unsigned char *ivec)
9 {
10 	int n;
11 	const unsigned char *iv = ivec;
12 
13 	while (len) {
14 		for(n=0; n<AES_BLOCK_SIZE && n<len; ++n)
15 		 	out[n] = in[n] ^ iv[n];
16 		for(; n<AES_BLOCK_SIZE; ++n)
17 		 	out[n] = iv[n];
18 		rk_aes_encrypt(out, out,key);
19 		iv = out;
20 		if (len<=AES_BLOCK_SIZE) break;
21 		len -= AES_BLOCK_SIZE;
22 		in  += AES_BLOCK_SIZE;
23 		out += AES_BLOCK_SIZE;
24 	}
25 	memcpy(ivec,iv,AES_BLOCK_SIZE);
26 }
27 
rk_crypto_cbc128_decrypt(const unsigned char * in,unsigned char * out,int len,const void * key,unsigned char * ivec)28 static void rk_crypto_cbc128_decrypt(const unsigned char *in, unsigned char *out,
29 		 int len, const void *key, unsigned char *ivec)
30 {
31 	int n;
32 	unsigned char c;
33 	unsigned char tmp_buf[AES_BLOCK_SIZE];
34 
35 	memset(tmp_buf, 0x00, sizeof(tmp_buf));
36 
37 	while (len) {
38 		rk_aes_decrypt(in, tmp_buf, key);
39 		for(n=0; n<AES_BLOCK_SIZE && n<len; ++n) {
40 			 c = in[n];
41 			 out[n] = tmp_buf[n] ^ ivec[n];
42 			 ivec[n] = c;
43 		}
44 		if (len<=AES_BLOCK_SIZE) {
45 			 for (; n<AES_BLOCK_SIZE; ++n)
46 				 ivec[n] = in[n];
47 			 break;
48 		}
49 		len -= AES_BLOCK_SIZE;
50 		in  += AES_BLOCK_SIZE;
51 		out += AES_BLOCK_SIZE;
52 	}
53 }
54 
55 
rk_crypto_cts_encrypt(const unsigned char * in,unsigned char * out,unsigned long length,const RK_AES_KEY * ks1,unsigned char * ivec,const int enc)56 static int rk_crypto_cts_encrypt(const unsigned char *in, unsigned char *out,
57 		unsigned long length, const RK_AES_KEY *ks1, unsigned char *ivec, const int enc)
58 {
59 	int k = 0, r = 0;
60 
61 	r = length % AES_BLOCK_SIZE;
62 	if (r) {
63 		k = length - r - AES_BLOCK_SIZE;
64 	} else {
65 		k = length;
66 	}
67 
68 	if (enc){
69 		unsigned char  peniv[AES_BLOCK_SIZE] = {0};
70 		memset(peniv, 0x00, sizeof(peniv));
71 
72 		rk_crypto_cbc128_encrypt(in, out, k, ks1, ivec);
73 
74 		if (r) {
75 			memcpy(peniv, in + k + AES_BLOCK_SIZE, r);
76 
77 			rk_crypto_cbc128_encrypt(in + k, out + k, AES_BLOCK_SIZE, ks1, ivec);
78 			memcpy(out + length - r, out + k, r);
79 			rk_crypto_cbc128_encrypt(peniv, out + k, AES_BLOCK_SIZE, ks1, ivec);
80 		}else{
81 			//swap last two block
82 			memcpy(peniv, out + length - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
83 			memcpy(out + length - AES_BLOCK_SIZE, out + length - 2*AES_BLOCK_SIZE, AES_BLOCK_SIZE);
84 			memcpy(out + length - 2*AES_BLOCK_SIZE, peniv, AES_BLOCK_SIZE);
85 		}
86 	}else{
87 		int i;
88 		unsigned char *pout_tmp = NULL;
89 		unsigned char  tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
90 
91 		memset(tmp1, 0x00, sizeof(tmp1));
92 		memset(tmp2, 0x00, sizeof(tmp2));
93 
94 		if(r == 0){
95 			rk_crypto_cbc128_decrypt(in, out, k-2*AES_BLOCK_SIZE, ks1, ivec);
96 			//swap last two block
97 			rk_crypto_cbc128_decrypt(in + length - AES_BLOCK_SIZE, out + length - 2*AES_BLOCK_SIZE,
98 										AES_BLOCK_SIZE, ks1, ivec);
99 			rk_crypto_cbc128_decrypt(in + length - 2*AES_BLOCK_SIZE, out + length - AES_BLOCK_SIZE,
100 										AES_BLOCK_SIZE, ks1, ivec);
101 		}else{
102 			rk_crypto_cbc128_decrypt(in, out, k, ks1, ivec);
103 			rk_aes_decrypt(in + k, tmp1, ks1);
104 
105 			memcpy(tmp2, in + k + AES_BLOCK_SIZE, r);
106 			memcpy(tmp2+r, tmp1+r, AES_BLOCK_SIZE-r);
107 
108 			//get last one plain text
109 			pout_tmp = out + k + AES_BLOCK_SIZE;
110 			for(i=0; i<AES_BLOCK_SIZE; i++,pout_tmp++)
111 		 		*pout_tmp = tmp1[i] ^ tmp2[i];
112 
113 			rk_aes_decrypt(tmp2, tmp2, ks1);
114 
115 			//get sencond to last plain text
116 			pout_tmp = out + k;
117 			for(i=0; i<AES_BLOCK_SIZE; i++,pout_tmp++)
118 		 		*pout_tmp = tmp2[i] ^ ivec[i];
119 		}
120 	}
121 
122 	return 0;
123 }
124 
125 
rk_aes_cts_encrypt(const unsigned char * in,unsigned char * out,unsigned long length,const unsigned char * key,const int key_len,unsigned char * ivec,const int enc)126 int rk_aes_cts_encrypt(const unsigned char *in, unsigned char *out,
127         unsigned long length, const unsigned char *key, const int key_len,
128         unsigned char *ivec, const int enc)
129 {
130 	RK_AES_KEY ks1;
131 
132 	if (in == NULL || out ==NULL || key == NULL)
133 		return -1;
134 
135 	if (key_len != 128/8 && key_len != 192/8 && key_len != 256/8)
136 		return -2;
137 
138 	if(length <= AES_BLOCK_SIZE)
139 		return -3;
140 
141 	if (enc) {
142 		rk_aes_set_encrypt_key(key, key_len * 8, &ks1);
143 	} else {
144 		rk_aes_set_decrypt_key(key, key_len * 8, &ks1);
145 	}
146 
147 	rk_crypto_cts_encrypt(in, out, length, &ks1, ivec, enc);
148 
149 	return 0;
150 }
151 
152 
153