1 /* $OpenBSD: gost89_keywrap.c,v 1.2 2014/11/09 19:27:29 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 <string.h> 53 54 #include <openssl/opensslconf.h> 55 56 #ifndef OPENSSL_NO_GOST 57 58 #include <openssl/gost.h> 59 60 #include "gost_locl.h" 61 62 static void 63 key_diversify_crypto_pro(GOST2814789_KEY *ctx, const unsigned char *inputKey, 64 const unsigned char *ukm, unsigned char *outputKey) 65 { 66 unsigned long k, s1, s2; 67 int i, mask; 68 unsigned char S[8]; 69 unsigned char *p; 70 71 memcpy(outputKey, inputKey, 32); 72 for (i = 0; i < 8; i++) { 73 /* Make array of integers from key */ 74 /* Compute IV S */ 75 s1 = 0, s2 = 0; 76 p = outputKey; 77 for (mask = 1; mask < 256; mask <<= 1) { 78 c2l(p, k); 79 if (mask & ukm[i]) { 80 s1 += k; 81 } else { 82 s2 += k; 83 } 84 } 85 p = S; 86 l2c (s1, p); 87 l2c (s2, p); 88 Gost2814789_set_key(ctx, outputKey, 256); 89 mask = 0; 90 Gost2814789_cfb64_encrypt(outputKey, outputKey, 32, ctx, S, 91 &mask, 1); 92 } 93 } 94 95 int 96 gost_key_wrap_crypto_pro(int nid, const unsigned char *keyExchangeKey, 97 const unsigned char *ukm, const unsigned char *sessionKey, 98 unsigned char *wrappedKey) 99 { 100 GOST2814789_KEY ctx; 101 unsigned char kek_ukm[32]; 102 103 Gost2814789_set_sbox(&ctx, nid); 104 key_diversify_crypto_pro(&ctx, keyExchangeKey, ukm, kek_ukm); 105 Gost2814789_set_key(&ctx, kek_ukm, 256); 106 memcpy(wrappedKey, ukm, 8); 107 Gost2814789_encrypt(sessionKey + 0, wrappedKey + 8 + 0, &ctx); 108 Gost2814789_encrypt(sessionKey + 8, wrappedKey + 8 + 8, &ctx); 109 Gost2814789_encrypt(sessionKey + 16, wrappedKey + 8 + 16, &ctx); 110 Gost2814789_encrypt(sessionKey + 24, wrappedKey + 8 + 24, &ctx); 111 GOST2814789IMIT(sessionKey, 32, wrappedKey + 40, nid, kek_ukm, ukm); 112 return 1; 113 } 114 115 int 116 gost_key_unwrap_crypto_pro(int nid, const unsigned char *keyExchangeKey, 117 const unsigned char *wrappedKey, unsigned char *sessionKey) 118 { 119 unsigned char kek_ukm[32], cek_mac[4]; 120 GOST2814789_KEY ctx; 121 122 Gost2814789_set_sbox(&ctx, nid); 123 /* First 8 bytes of wrapped Key is ukm */ 124 key_diversify_crypto_pro(&ctx, keyExchangeKey, wrappedKey, kek_ukm); 125 Gost2814789_set_key(&ctx, kek_ukm, 256); 126 Gost2814789_decrypt(wrappedKey + 8 + 0, sessionKey + 0, &ctx); 127 Gost2814789_decrypt(wrappedKey + 8 + 8, sessionKey + 8, &ctx); 128 Gost2814789_decrypt(wrappedKey + 8 + 16, sessionKey + 16, &ctx); 129 Gost2814789_decrypt(wrappedKey + 8 + 24, sessionKey + 24, &ctx); 130 131 GOST2814789IMIT(sessionKey, 32, cek_mac, nid, kek_ukm, wrappedKey); 132 if (memcmp(cek_mac, wrappedKey + 40, 4)) 133 return 0; 134 135 return 1; 136 } 137 138 #endif 139