1 /* $OpenBSD: gostr341194.c,v 1.5 2015/09/10 15:56:25 jsing Exp $ */ 2 /* 3 * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 4 * Copyright (c) 2005-2006 Cryptocom LTD 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * 3. All advertising materials mentioning features or use of this 19 * software must display the following acknowledgment: 20 * "This product includes software developed by the OpenSSL Project 21 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 22 * 23 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 24 * endorse or promote products derived from this software without 25 * prior written permission. For written permission, please contact 26 * openssl-core@openssl.org. 27 * 28 * 5. Products derived from this software may not be called "OpenSSL" 29 * nor may "OpenSSL" appear in their names without prior written 30 * permission of the OpenSSL Project. 31 * 32 * 6. Redistributions of any form whatsoever must retain the following 33 * acknowledgment: 34 * "This product includes software developed by the OpenSSL Project 35 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 36 * 37 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 38 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 43 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 46 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 47 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 48 * OF THE POSSIBILITY OF SUCH DAMAGE. 49 * ==================================================================== 50 */ 51 52 #include <string.h> 53 54 #include <openssl/opensslconf.h> 55 56 #ifndef OPENSSL_NO_GOST 57 #include <openssl/crypto.h> 58 #include <openssl/objects.h> 59 #include <openssl/gost.h> 60 61 #include "gost_locl.h" 62 63 /* Following functions are various bit meshing routines used in 64 * GOST R 34.11-94 algorithms */ 65 static void 66 swap_bytes(unsigned char *w, unsigned char *k) 67 { 68 int i, j; 69 70 for (i = 0; i < 4; i++) 71 for (j = 0; j < 8; j++) 72 k[i + 4 * j] = w[8 * i + j]; 73 } 74 75 /* was A_A */ 76 static void 77 circle_xor8(const unsigned char *w, unsigned char *k) 78 { 79 unsigned char buf[8]; 80 int i; 81 82 memcpy(buf, w, 8); 83 memmove(k, w + 8, 24); 84 for (i = 0; i < 8; i++) 85 k[i + 24] = buf[i] ^ k[i]; 86 } 87 88 /* was R_R */ 89 static void 90 transform_3(unsigned char *data) 91 { 92 unsigned short int acc; 93 94 acc = (data[0] ^ data[2] ^ data[4] ^ data[6] ^ data[24] ^ data[30]) | 95 ((data[1] ^ data[3] ^ data[5] ^ data[7] ^ data[25] ^ data[31]) << 8); 96 memmove(data, data + 2, 30); 97 data[30] = acc & 0xff; 98 data[31] = acc >> 8; 99 } 100 101 /* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/ 102 static int 103 add_blocks(int n, unsigned char *left, const unsigned char *right) 104 { 105 int i; 106 int carry = 0; 107 int sum; 108 109 for (i = 0; i < n; i++) { 110 sum = (int)left[i] + (int)right[i] + carry; 111 left[i] = sum & 0xff; 112 carry = sum >> 8; 113 } 114 return carry; 115 } 116 117 /* Xor two sequences of bytes */ 118 static void 119 xor_blocks(unsigned char *result, const unsigned char *a, 120 const unsigned char *b, size_t len) 121 { 122 size_t i; 123 124 for (i = 0; i < len; i++) 125 result[i] = a[i] ^ b[i]; 126 } 127 128 /* 129 * Calculate H(i+1) = Hash(Hi,Mi) 130 * Where H and M are 32 bytes long 131 */ 132 static int 133 hash_step(GOSTR341194_CTX *c, unsigned char *H, const unsigned char *M) 134 { 135 unsigned char U[32], W[32], V[32], S[32], Key[32]; 136 int i; 137 138 /* Compute first key */ 139 xor_blocks(W, H, M, 32); 140 swap_bytes(W, Key); 141 /* Encrypt first 8 bytes of H with first key */ 142 Gost2814789_set_key(&c->cipher, Key, 256); 143 Gost2814789_encrypt(H, S, &c->cipher); 144 145 /* Compute second key */ 146 circle_xor8(H, U); 147 circle_xor8(M, V); 148 circle_xor8(V, V); 149 xor_blocks(W, U, V, 32); 150 swap_bytes(W, Key); 151 /* encrypt second 8 bytes of H with second key */ 152 Gost2814789_set_key(&c->cipher, Key, 256); 153 Gost2814789_encrypt(H+8, S+8, &c->cipher); 154 155 /* compute third key */ 156 circle_xor8(U, U); 157 U[31] = ~U[31]; 158 U[29] = ~U[29]; 159 U[28] = ~U[28]; 160 U[24] = ~U[24]; 161 U[23] = ~U[23]; 162 U[20] = ~U[20]; 163 U[18] = ~U[18]; 164 U[17] = ~U[17]; 165 U[14] = ~U[14]; 166 U[12] = ~U[12]; 167 U[10] = ~U[10]; 168 U[8] = ~U[8]; 169 U[7] = ~U[7]; 170 U[5] = ~U[5]; 171 U[3] = ~U[3]; 172 U[1] = ~U[1]; 173 circle_xor8(V, V); 174 circle_xor8(V, V); 175 xor_blocks(W, U, V, 32); 176 swap_bytes(W, Key); 177 /* encrypt third 8 bytes of H with third key */ 178 Gost2814789_set_key(&c->cipher, Key, 256); 179 Gost2814789_encrypt(H+16, S+16, &c->cipher); 180 181 /* Compute fourth key */ 182 circle_xor8(U, U); 183 circle_xor8(V, V); 184 circle_xor8(V, V); 185 xor_blocks(W, U, V, 32); 186 swap_bytes(W, Key); 187 /* Encrypt last 8 bytes with fourth key */ 188 Gost2814789_set_key(&c->cipher, Key, 256); 189 Gost2814789_encrypt(H+24, S+24, &c->cipher); 190 191 for (i = 0; i < 12; i++) 192 transform_3(S); 193 xor_blocks(S, S, M, 32); 194 transform_3(S); 195 xor_blocks(S, S, H, 32); 196 for (i = 0; i < 61; i++) 197 transform_3(S); 198 memcpy(H, S, 32); 199 return 1; 200 } 201 202 int 203 GOSTR341194_Init(GOSTR341194_CTX *c, int nid) 204 { 205 memset(c, 0, sizeof(*c)); 206 return Gost2814789_set_sbox(&c->cipher, nid); 207 } 208 209 static void 210 GOSTR341194_block_data_order(GOSTR341194_CTX *ctx, const unsigned char *p, 211 size_t num) 212 { 213 int i; 214 215 for (i = 0; i < num; i++) { 216 hash_step(ctx, ctx->H, p); 217 add_blocks(32, ctx->S, p); 218 p += 32; 219 } 220 } 221 222 #define DATA_ORDER_IS_LITTLE_ENDIAN 223 224 #define HASH_CBLOCK GOSTR341194_CBLOCK 225 #define HASH_LONG GOSTR341194_LONG 226 #define HASH_CTX GOSTR341194_CTX 227 #define HASH_UPDATE GOSTR341194_Update 228 #define HASH_TRANSFORM GOSTR341194_Transform 229 #define HASH_NO_FINAL 1 230 #define HASH_BLOCK_DATA_ORDER GOSTR341194_block_data_order 231 232 #include "md32_common.h" 233 234 int 235 GOSTR341194_Final(unsigned char *md, GOSTR341194_CTX * c) 236 { 237 unsigned char *p = (unsigned char *)c->data; 238 unsigned char T[32]; 239 240 if (c->num > 0) { 241 memset(p + c->num, 0, 32 - c->num); 242 hash_step(c, c->H, p); 243 add_blocks(32, c->S, p); 244 } 245 246 p = T; 247 HOST_l2c(c->Nl, p); 248 HOST_l2c(c->Nh, p); 249 memset(p, 0, 32 - 8); 250 hash_step(c, c->H, T); 251 hash_step(c, c->H, c->S); 252 253 memcpy(md, c->H, 32); 254 255 return 1; 256 } 257 258 unsigned char * 259 GOSTR341194(const unsigned char *d, size_t n, unsigned char *md, int nid) 260 { 261 GOSTR341194_CTX c; 262 static unsigned char m[GOSTR341194_LENGTH]; 263 264 if (md == NULL) 265 md = m; 266 if (!GOSTR341194_Init(&c, nid)) 267 return 0; 268 GOSTR341194_Update(&c, d, n); 269 GOSTR341194_Final(md, &c); 270 explicit_bzero(&c, sizeof(c)); 271 return (md); 272 } 273 #endif 274