OpenCores
URL https://opencores.org/ocsvn/gost28147-89/gost28147-89/trunk

Subversion Repositories gost28147-89

[/] [gost28147-89/] [trunk/] [utils/] [gost89.c] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 fanatid
#include <assert.h>
2
#include <string.h>
3
 
4
#include "gost89.h"
5
 
6
 
7
// Substitution blocks from RFC 4357, item 11.2
8
gost_subst_block GOST28147_89_RFC = {
9
  {0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3},
10
  {0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9},
11
  {0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB},
12
  {0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3},
13
  {0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2},
14
  {0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE},
15
  {0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC},
16
  {0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC}
17
};
18
 
19
 
20
void gost_init(gost_ctx *c, const gost_subst_block* b) {
21
  int i;
22
 
23
  if (!b)
24
    b = &GOST28147_89_RFC;
25
 
26
  for (i = 0; i < 256; ++i) {
27
    c->k21[i] = (b->k2[i>>4]<<4 | b->k1 [i&15]);
28
    c->k43[i] = (b->k4[i>>4]<<4 | b->k3 [i&15])<<8;
29
    c->k65[i] = (b->k6[i>>4]<<4 | b->k5 [i&15])<<16;
30
    c->k87[i] = (b->k8[i>>4]<<4 | b->k7 [i&15])<<24;
31
  }
32
}
33
 
34
void gost_destroy(gost_ctx *c) {
35
  int i;
36
 
37
  for (i = 0; i < 8; ++i)
38
    c->k[i] = 0;
39
  for (i = 0; i < 256; ++i)
40
    c->k87[i] = c->k65[i] = c->k43[i] = c->k21[i] = 0;
41
}
42
 
43
void gost_set_key(gost_ctx *c, const uint8_t *k) {
44
  int i, j;
45
  for (i=0, j=0; i < 8; i+=1, j+=4)
46
    c->k[i] = (k[j]<<24) | (k[j+1]<<16) | (k[j+2]<<8) | k[j+3];
47
}
48
 
49
void gost_get_key(gost_ctx *c, uint8_t *k) {
50
  int i, j;
51
 
52
  for (i=0, j=0; i < 8; i+=1, j+=4) {
53
    k[j]   = (uint8_t) ((c->k[i]    ) &0xFF);
54
    k[j+1] = (uint8_t) ((c->k[i]>>8 ) &0xFF);
55
    k[j+2] = (uint8_t) ((c->k[i]>>16) &0xFF);
56
    k[j+3] = (uint8_t) ((c->k[i]>>24) &0xFF);
57
  }
58
}
59
 
60
inline uint32_t f(gost_ctx *c, uint32_t x) {
61
  x = c->k87[x>>24 & 255] | c->k65[x>>16 & 255] |
62
      c->k43[x>> 8 & 255] | c->k21[x     & 255];
63
  return x<<11 | x>>(32-11);
64
}
65
 
66
inline void gost_encrypt_block(gost_ctx *c, const uint8_t *in, uint8_t *out) {
67
  register uint32_t n1, n2;
68
  n1 = (in[0]<<24) | (in[1]<<16) | (in[2]<<8) | in[3];
69
  n2 = (in[4]<<24) | (in[5]<<16) | (in[6]<<8) | in[7];
70
 
71
  n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
72
  n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
73
  n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
74
  n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
75
 
76
  n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
77
  n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
78
  n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
79
  n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
80
 
81
  n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
82
  n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
83
  n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
84
  n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
85
 
86
  n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
87
  n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
88
  n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
89
  n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
90
 
91
  out[0] = (uint8_t) (n2>>24);       out[1] = (uint8_t) ((n2>>16)&0xff);
92
  out[2] = (uint8_t) ((n2>>8)&0xff); out[3] = (uint8_t) (n2&0xff);
93
  out[4] = (uint8_t) (n1>>24);       out[5] = (uint8_t) ((n1>>16)&0xff);
94
  out[6] = (uint8_t) ((n1>>8)&0xff); out[7] = (uint8_t) (n1&0xff);
95
}
96
 
97
inline void gost_decrypt_block(gost_ctx *c, const uint8_t *in, uint8_t *out) {
98
  register uint32_t n1, n2;
99
  n1 = (in[0]<<24) | (in[1]<<16) | (in[2]<<8) | in[3];
100
  n2 = (in[4]<<24) | (in[5]<<16) | (in[6]<<8) | in[7];
101
 
102
  n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
103
  n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
104
  n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
105
  n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
106
 
107
  n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
108
  n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
109
  n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
110
  n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
111
 
112
  n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
113
  n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
114
  n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
115
  n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
116
 
117
  n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
118
  n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
119
  n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
120
  n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
121
 
122
  out[0] = (uint8_t) (n2>>24);       out[1] = (uint8_t) ((n2>>16)&0xff);
123
  out[2] = (uint8_t) ((n2>>8)&0xff); out[3] = (uint8_t) (n2&0xff);
124
  out[4] = (uint8_t) (n1>>24);       out[5] = (uint8_t) ((n1>>16)&0xff);
125
  out[6] = (uint8_t) ((n1>>8)&0xff); out[7] = (uint8_t) (n1&0xff);
126
}
127
 
128
void gost_ecb_encrypt(gost_ctx *ctx, const uint8_t *in, uint8_t *out, size_t blocks) {
129
  while (blocks--) {
130
    gost_encrypt_block(ctx, in, out);
131
    in  += 8;
132
    out += 8;
133
  }
134
}
135
 
136
void gost_ecb_decrypt(gost_ctx *ctx, const uint8_t *in, uint8_t *out, size_t blocks) {
137
  while (blocks--) {
138
    gost_decrypt_block(ctx, in, out);
139
    in  += 8;
140
    out += 8;
141
  }
142
}
143
 
144
void gost_cfb_encrypt(gost_ctx *ctx, const uint8_t *iv, const uint8_t *in, uint8_t *out, size_t blocks) {
145
  uint8_t cur_iv[8], gamma[8];
146
  memcpy((void*) &cur_iv[0], (const void*) &iv[0], 8);
147
  while (blocks--) {
148
    gost_encrypt_block(ctx, cur_iv, gamma);
149
    for (int i = 0; i < 8; ++i) {
150
      out[i] = in[i] ^ gamma[i];
151
      cur_iv[i] = out[i];
152
    }
153
    in  += 8;
154
    out += 8;
155
  }
156
}
157
 
158
void gost_cfb_decrypt(gost_ctx *ctx, const uint8_t *iv, const uint8_t *in, uint8_t *out, size_t blocks) {
159
  uint8_t cur_iv[8], gamma[8];
160
  memcpy((void*) &cur_iv[0], (const void*) &iv[0], 8);
161
  while (blocks--) {
162
    gost_encrypt_block(ctx, cur_iv, gamma);
163
    for (int i = 0; i < 8; ++i) {
164
      out[i] = in[i] ^ gamma[i];
165
      cur_iv[i] = in[i];
166
    }
167
    in  += 8;
168
    out += 8;
169
  }
170
}
171
 
172
inline void gost_mac_block(gost_ctx *c, const uint8_t *in, uint8_t *out) {
173
  register uint32_t n1, n2;
174
  n1 = (in[0]<<24) | (in[1]<<16) | (in[2]<<8) | in[3];
175
  n2 = (in[4]<<24) | (in[5]<<16) | (in[6]<<8) | in[7];
176
 
177
  n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
178
  n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
179
  n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
180
  n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
181
 
182
  n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
183
  n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
184
  n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
185
  n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
186
 
187
  out[0] = (uint8_t) (n2>>24);       out[1] = (uint8_t) ((n2>>16)&0xff);
188
  out[2] = (uint8_t) ((n2>>8)&0xff); out[3] = (uint8_t) (n2&0xff);
189
  out[4] = (uint8_t) (n1>>24);       out[5] = (uint8_t) ((n1>>16)&0xff);
190
  out[6] = (uint8_t) ((n1>>8)&0xff); out[7] = (uint8_t) (n1&0xff);
191
}
192
 
193
void gost_mac(gost_ctx *ctx, const uint8_t *data, size_t data_len, uint8_t *mac, const size_t mac_len) {
194
  assert(data_len >= 16);
195
  assert(mac_len <= 32);
196
 
197
  uint8_t out[8] = {0};
198
 
199
  while (data_len > 0) {
200
    uint8_t in[8] = {0};
201
    memcpy((void*) &in[0], (const void*) &data[0], data_len < 8 ? data_len : 8);
202
 
203
    for (int i = 0; i < 8; ++i)
204
      in[i] = in[i] ^ out[i];
205
    gost_mac_block(ctx, in, &out[0]);
206
 
207
    data_len -= 8;
208
    data += 8;
209
  }
210
 
211
  uint8_t nbytes = (mac_len>>3) + ((mac_len&7) > 0 ? 1 : 0);
212
  memset((void*) mac, 0, nbytes);
213
 
214
 
215
  uint32_t fmac = (out[0]<<24) | (out[1]<<16) | (out[2]<<8) | out[3];
216
  fmac <<= 32 - mac_len;
217
  out[0] = (uint8_t) (fmac>>24);       out[1] = (uint8_t) ((fmac>>16)&0xff);
218
  out[2] = (uint8_t) ((fmac>>8)&0xff); out[3] = (uint8_t) (fmac&0xff);
219
 
220
  for (int i = 0; i < nbytes; ++i)
221
    mac[i] = out[i];
222
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.