xref: /OK3568_Linux_fs/external/security/librkcrypto/test/c_mode/sm4_ctr.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "sm4_core.h"
5 
6 struct ctr_state {
7 	unsigned char ivec[SM4_BLOCK_SIZE];
8 	unsigned char ecount[SM4_BLOCK_SIZE];
9 	unsigned int num;
10 };
11 
rk_init_ctr(struct ctr_state * state,const unsigned char * iv)12 static void rk_init_ctr(struct ctr_state * state, const unsigned char *iv)
13 {
14 	state->num = 0;
15 	memset(state->ecount, 0, SM4_BLOCK_SIZE);
16 	memcpy(state->ivec, iv, SM4_BLOCK_SIZE);
17 }
18 
19 /* increment counter (128-bit int) by 1 */
rk_ctr128_inc(unsigned char * counter)20 static void rk_ctr128_inc(unsigned char *counter) {
21 	unsigned int n=SM4_BLOCK_SIZE;
22 	unsigned char  c;
23 
24 	do {
25 		--n;
26 		c = counter[n];
27 		++c;
28 		counter[n] = c;
29 		if (c) return;
30 	} while (n);
31 }
32 
rk_crypto_ctr128_encrypt(void * ctx,const unsigned char * in,unsigned char * out,unsigned int len,unsigned char * ivec,unsigned char * ecount_buf,unsigned int * num,block128_f block)33 static void rk_crypto_ctr128_encrypt(void *ctx, const unsigned char *in, unsigned char *out,
34 			unsigned int len, unsigned char *ivec, unsigned char *ecount_buf,
35 			unsigned int *num, block128_f block)
36 {
37 	unsigned int n, l=0;
38 
39 	n = *num;
40 	while (l<len) {
41 		if (n==0) {
42 			(*block)(ivec, ecount_buf, ctx);
43  			rk_ctr128_inc(ivec);
44 		}
45 		out[l] = in[l] ^ ecount_buf[n];
46 		++l;
47 		n = (n+1) % SM4_BLOCK_SIZE;
48 	}
49 
50 	*num = n;
51 }
52 
rk_sm4_ctr_encrypt(const unsigned char * in,unsigned char * out,unsigned int length,const unsigned char * key,const int key_len,unsigned char * ivec,const int enc)53 int rk_sm4_ctr_encrypt(const unsigned char *in, unsigned char *out,
54         unsigned int length, const unsigned char *key, const int key_len,
55         unsigned char *ivec, const int enc)
56 {
57 	sm4_context  ctx;
58 	struct ctr_state state;
59 
60 	if(key_len != 16)
61 		return -1;
62 
63 	if(length == 0)
64 		return -1;
65 
66 	rk_init_ctr(&state, ivec);
67 	rk_sm4_setkey_enc(&ctx, key);
68 	rk_crypto_ctr128_encrypt((void*)(&ctx),in, out, length,
69 				state.ivec, state.ecount,
70 				&state.num, rk_rk_sm4_crypt_ecb);
71 
72 	return 0;
73 }
74 
75 
76