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