OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
gost_keywrap.c
Go to the documentation of this file.
1 /**********************************************************************
2  * keywrap.c *
3  * Copyright (c) 2005-2006 Cryptocom LTD *
4  * This file is distributed under the same license as OpenSSL *
5  * *
6  * Implementation of CryptoPro key wrap algorithm, as defined in *
7  * RFC 4357 p 6.3 and 6.4 *
8  * Doesn't need OpenSSL *
9  **********************************************************************/
10 #include <string.h>
11 #include "gost89.h"
12 #include "gost_keywrap.h"
13 
14 /* Diversifies key using random UserKey Material
15  * Implements RFC 4357 p 6.5 key diversification algorithm
16  *
17  * inputKey - 32byte key to be diversified
18  * ukm - 8byte user key material
19  * outputKey - 32byte buffer to store diversified key
20  *
21  */
22 void keyDiversifyCryptoPro(gost_ctx *ctx,const unsigned char *inputKey, const unsigned char *ukm, unsigned char *outputKey)
23  {
24 
25  u4 k,s1,s2;
26  int i,j,mask;
27  unsigned char S[8];
28  memcpy(outputKey,inputKey,32);
29  for (i=0;i<8;i++)
30  {
31  /* Make array of integers from key */
32  /* Compute IV S*/
33  s1=0,s2=0;
34  for (j=0,mask=1;j<8;j++,mask<<=1)
35  {
36  k=((u4)outputKey[4*j])|(outputKey[4*j+1]<<8)|
37  (outputKey[4*j+2]<<16)|(outputKey[4*j+3]<<24);
38  if (mask & ukm[i])
39  {
40  s1+=k;
41  }
42  else
43  {
44  s2+=k;
45  }
46  }
47  S[0]=(unsigned char)(s1&0xff);
48  S[1]=(unsigned char)((s1>>8)&0xff);
49  S[2]=(unsigned char)((s1>>16)&0xff);
50  S[3]=(unsigned char)((s1>>24)&0xff);
51  S[4]=(unsigned char)(s2&0xff);
52  S[5]=(unsigned char)((s2>>8)&0xff);
53  S[6]=(unsigned char)((s2>>16)&0xff);
54  S[7]=(unsigned char)((s2>>24)&0xff);
55  gost_key(ctx,outputKey);
56  gost_enc_cfb(ctx,S,outputKey,outputKey,4);
57  }
58  }
59 
60 
61 /*
62  * Wraps key using RFC 4357 6.3
63  * ctx - gost encryption context, initialized with some S-boxes
64  * keyExchangeKey (KEK) 32-byte (256-bit) shared key
65  * ukm - 8 byte (64 bit) user key material,
66  * sessionKey - 32-byte (256-bit) key to be wrapped
67  * wrappedKey - 44-byte buffer to store wrapped key
68  */
69 
70 int keyWrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, const unsigned char *ukm,
71  const unsigned char *sessionKey, unsigned char *wrappedKey)
72  {
73  unsigned char kek_ukm[32];
74  keyDiversifyCryptoPro(ctx,keyExchangeKey,ukm,kek_ukm);
75  gost_key(ctx,kek_ukm);
76  memcpy(wrappedKey,ukm,8);
77  gost_enc(ctx,sessionKey,wrappedKey+8,4);
78  gost_mac_iv(ctx,32,ukm,sessionKey,32,wrappedKey+40);
79  return 1;
80  }
81 /*
82  * Unwraps key using RFC 4357 6.4
83  * ctx - gost encryption context, initialized with some S-boxes
84  * keyExchangeKey 32-byte shared key
85  * wrappedKey 44 byte key to be unwrapped (concatenation of 8-byte UKM,
86  * 32 byte encrypted key and 4 byte MAC
87  *
88  * sessionKEy - 32byte buffer to store sessionKey in
89  * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match
90  */
91 
92 int keyUnwrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey,
93  const unsigned char *wrappedKey, unsigned char *sessionKey)
94  {
95  unsigned char kek_ukm[32],cek_mac[4];
96  keyDiversifyCryptoPro(ctx,keyExchangeKey,wrappedKey
97  /* First 8 bytes of wrapped Key is ukm */
98  ,kek_ukm);
99  gost_key(ctx,kek_ukm);
100  gost_dec(ctx,wrappedKey+8,sessionKey,4);
101  gost_mac_iv(ctx,32,wrappedKey,sessionKey,32,cek_mac);
102  if (memcmp(cek_mac,wrappedKey+40,4))
103  {
104  return 0;
105  }
106  return 1;
107  }
108 
109