1 /* $OpenBSD: gost89_params.c,v 1.1 2014/11/09 19:17:13 miod 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 <stdlib.h> 53 54 #include <openssl/opensslconf.h> 55 56 #ifndef OPENSSL_NO_GOST 57 #include <openssl/objects.h> 58 #include <openssl/gost.h> 59 60 #include "gost_locl.h" 61 62 /* Substitution blocks from test examples for GOST R 34.11-94*/ 63 static const gost_subst_block GostR3411_94_TestParamSet = { 64 {0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC}, 65 {0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC}, 66 {0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE}, 67 {0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2}, 68 {0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3}, 69 {0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB}, 70 {0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9}, 71 {0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3} 72 }; 73 74 /* Substitution blocks for hash function 1.2.643.2.9.1.6.1 */ 75 static const gost_subst_block GostR3411_94_CryptoProParamSet = { 76 {0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC}, 77 {0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB}, 78 {0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3}, 79 {0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5}, 80 {0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3}, 81 {0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD}, 82 {0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8}, 83 {0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF} 84 }; 85 86 /* Test paramset from GOST 28147 */ 87 gost_subst_block Gost28147_TestParamSet = { 88 {0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8}, 89 {0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD}, 90 {0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4}, 91 {0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4}, 92 {0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8}, 93 {0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB}, 94 {0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5}, 95 {0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6} 96 }; 97 98 99 /* 1.2.643.2.2.31.1 */ 100 static const gost_subst_block Gost28147_CryptoProParamSetA = { 101 {0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4}, 102 {0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE}, 103 {0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6}, 104 {0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6}, 105 {0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6}, 106 {0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9}, 107 {0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1}, 108 {0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5} 109 }; 110 111 /* 1.2.643.2.2.31.2 */ 112 static const gost_subst_block Gost28147_CryptoProParamSetB = { 113 {0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC}, 114 {0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE}, 115 {0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5}, 116 {0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3}, 117 {0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8}, 118 {0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4}, 119 {0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE}, 120 {0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF} 121 }; 122 123 /* 1.2.643.2.2.31.3 */ 124 static const gost_subst_block Gost28147_CryptoProParamSetC = { 125 {0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8}, 126 {0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7}, 127 {0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD}, 128 {0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7}, 129 {0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4}, 130 {0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB}, 131 {0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3}, 132 {0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3} 133 }; 134 135 /* 1.2.643.2.2.31.4 */ 136 static const gost_subst_block Gost28147_CryptoProParamSetD = { 137 {0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE}, 138 {0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7}, 139 {0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6}, 140 {0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1}, 141 {0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8}, 142 {0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2}, 143 {0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1}, 144 {0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3} 145 }; 146 147 static const gost_subst_block Gost28147_TC26ParamSetZ = { 148 {0x1,0x7,0xe,0xd,0x0,0x5,0x8,0x3,0x4,0xf,0xa,0x6,0x9,0xc,0xb,0x2}, 149 {0x8,0xe,0x2,0x5,0x6,0x9,0x1,0xc,0xf,0x4,0xb,0x0,0xd,0xa,0x3,0x7}, 150 {0x5,0xd,0xf,0x6,0x9,0x2,0xc,0xa,0xb,0x7,0x8,0x1,0x4,0x3,0xe,0x0}, 151 {0x7,0xf,0x5,0xa,0x8,0x1,0x6,0xd,0x0,0x9,0x3,0xe,0xb,0x4,0x2,0xc}, 152 {0xc,0x8,0x2,0x1,0xd,0x4,0xf,0x6,0x7,0x0,0xa,0x5,0x3,0xe,0x9,0xb}, 153 {0xb,0x3,0x5,0x8,0x2,0xf,0xa,0xd,0xe,0x1,0x7,0x4,0xc,0x9,0x6,0x0}, 154 {0x6,0x8,0x2,0x3,0x9,0xa,0x5,0xc,0x1,0xe,0x4,0x7,0xb,0xd,0x0,0xf}, 155 {0xc,0x4,0x6,0x2,0xa,0x5,0xb,0x9,0xe,0x8,0xd,0x7,0x0,0x3,0xf,0x1} 156 }; 157 158 static const unsigned char CryptoProKeyMeshingKey[] = { 159 0x69, 0x00, 0x72, 0x22, 0x64, 0xC9, 0x04, 0x23, 160 0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4, 161 0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12, 162 0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B 163 }; 164 165 static const struct gost89_parameters_info { 166 int nid; 167 const gost_subst_block *sblock; 168 int key_meshing; 169 } gost_cipher_list[] = 170 { 171 {NID_id_Gost28147_89_CryptoPro_A_ParamSet,&Gost28147_CryptoProParamSetA,1}, 172 {NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,1}, 173 {NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1}, 174 {NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1}, 175 {NID_id_tc26_gost_28147_param_Z,&Gost28147_TC26ParamSetZ,1}, 176 {NID_id_Gost28147_89_TestParamSet,&Gost28147_TestParamSet,0}, 177 {NID_id_GostR3411_94_TestParamSet,&GostR3411_94_TestParamSet,0}, 178 {NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0}, 179 {NID_undef,NULL,0} 180 }; 181 182 int 183 Gost2814789_set_sbox(GOST2814789_KEY *key, int nid) 184 { 185 int i; 186 const gost_subst_block *b = NULL; 187 unsigned int t; 188 189 for (i = 0; gost_cipher_list[i].nid != NID_undef; i++) { 190 if (gost_cipher_list[i].nid != nid) 191 continue; 192 193 b = gost_cipher_list[i].sblock; 194 key->key_meshing = gost_cipher_list[i].key_meshing; 195 break; 196 } 197 198 if (b == NULL) 199 return 0; 200 201 for (i = 0; i < 256; i++) { 202 t = (unsigned int)(b->k8[i >> 4] <<4 | b->k7 [i & 15]) << 24; 203 key->k87[i] = (t << 11) | (t >> 21); 204 t = (unsigned int)(b->k6[i >> 4] <<4 | b->k5 [i & 15]) << 16; 205 key->k65[i] = (t << 11) | (t >> 21); 206 t = (unsigned int)(b->k4[i >> 4] <<4 | b->k3 [i & 15]) << 8; 207 key->k43[i] = (t << 11) | (t >> 21); 208 t = (unsigned int)(b->k2[i >> 4] <<4 | b->k1 [i & 15]) << 0; 209 key->k21[i] = (t << 11) | (t >> 21); 210 } 211 212 return 1; 213 } 214 215 int 216 Gost2814789_set_key(GOST2814789_KEY *key, const unsigned char *userKey, 217 const int bits) 218 { 219 int i; 220 221 if (bits != 256) 222 return 0; 223 224 for (i = 0; i < 8; i++) 225 c2l(userKey, key->key[i]); 226 227 key->count = 0; 228 229 return 1; 230 } 231 232 void 233 Gost2814789_cryptopro_key_mesh(GOST2814789_KEY *key) 234 { 235 unsigned char newkey[32]; 236 237 Gost2814789_decrypt(CryptoProKeyMeshingKey + 0, newkey + 0, key); 238 Gost2814789_decrypt(CryptoProKeyMeshingKey + 8, newkey + 8, key); 239 Gost2814789_decrypt(CryptoProKeyMeshingKey + 16, newkey + 16, key); 240 Gost2814789_decrypt(CryptoProKeyMeshingKey + 24, newkey + 24, key); 241 242 Gost2814789_set_key(key, newkey, 256); 243 } 244 #endif 245