summaryrefslogtreecommitdiffstats
path: root/engines/ccgost/keywrap.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2006-09-17 13:00:18 +0000
committerDr. Stephen Henson <steve@openssl.org>2006-09-17 13:00:18 +0000
commita04549cc755408ff2dcab209fd87d3e46f7d662a (patch)
treee4778866a61dddb7fb9ef4465490ad48de919645 /engines/ccgost/keywrap.c
parentbc7535bc7fe30fbba222c316a3957da7d906603b (diff)
GOST public key algorithm ENGINE donated to the OpenSSL by Cryptocom.
Very early version, doesn't do much yet, not even added to the build system.
Diffstat (limited to 'engines/ccgost/keywrap.c')
-rw-r--r--engines/ccgost/keywrap.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/engines/ccgost/keywrap.c b/engines/ccgost/keywrap.c
new file mode 100644
index 0000000000..4e7d675a73
--- /dev/null
+++ b/engines/ccgost/keywrap.c
@@ -0,0 +1,97 @@
+/**********************************************************************
+ * keywrap.c *
+ * Copyright (c) 2005-2006 Cryptocom LTD *
+ * This file is distributed under the same license as OpenSSL *
+ * *
+ * Implementation of CryptoPro key wrap algorithm, as defined in *
+ * RFC 4357 p 6.3 and 6.4 *
+ * Doesn't need OpenSSL *
+ **********************************************************************/
+#include <string.h>
+#include "gost89.h"
+#include "keywrap.h"
+
+/* Diversifies key using random UserKey Material
+ * Implements RFC 4357 p 6.5 key diversification algorithm
+ *
+ * inputKey - 32byte key to be diversified
+ * ukm - 8byte user key material
+ * outputKey - 32byte buffer to store diversified key
+ *
+ */
+void keyDiversifyCryptoPro(gost_ctx *ctx,const unsigned char *inputKey, const unsigned char *ukm, unsigned char *outputKey)
+{
+
+ u4 k,s1,s2;
+ int i,j,mask;
+ unsigned char S[8];
+ memcpy(outputKey,inputKey,32);
+ for (i=0;i<8;i++) {
+ /* Make array of integers from key */
+ /* Compute IV S*/
+ s1=0,s2=0;
+ for (j=0,mask=1;j<8;j++,mask<<=1) {
+ k=((u4)outputKey[4*j])|(outputKey[4*j+1]<<8)|
+ (outputKey[4*j+2]<<16)|(outputKey[4*j+3]<<24);
+ if (mask & ukm[i]) {
+ s1+=k;
+ } else {
+ s2+=k;
+ }
+ }
+ S[0]=s1&0xff; S[1]=(s1>>8)&0xff; S[2]=(s1>>16)&0xff; S[3]=(s1>>24)&0xff;
+ S[4]=s2&0xff; S[5]=(s2>>8)&0xff; S[6]=(s2>>16)&0xff; S[7]=(s2>>24)&0xff;
+ gost_key(ctx,outputKey);
+ gost_enc_cfb(ctx,S,outputKey,outputKey,4);
+ }
+}
+
+
+/*
+ * Wraps key using RFC 4357 6.3
+ * ctx - gost encryption context, initialized with some S-boxes
+ * keyExchangeKey (KEK) 32-byte (256-bit) shared key
+ * ukm - 8 byte (64 bit) user key material,
+ * sessionKey - 32-byte (256-bit) key to be wrapped
+ * wrappedKey - 44-byte buffer to store wrapped key
+ */
+
+int keyWrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, const unsigned char *ukm,
+ const unsigned char *sessionKey, unsigned char *wrappedKey)
+{
+ unsigned char kek_ukm[32];
+ keyDiversifyCryptoPro(ctx,keyExchangeKey,ukm,kek_ukm);
+ gost_key(ctx,kek_ukm);
+ memcpy(wrappedKey,ukm,8);
+ gost_enc(ctx,sessionKey,wrappedKey+8,4);
+ gost_mac_iv(ctx,32,ukm,sessionKey,32,wrappedKey+40);
+ return 1;
+}
+/*
+ * Unwraps key using RFC 4357 6.4
+ * ctx - gost encryption context, initialized with some S-boxes
+ * keyExchangeKey 32-byte shared key
+ * wrappedKey 44 byte key to be unwrapped (concatenation of 8-byte UKM,
+ * 32 byte encrypted key and 4 byte MAC
+ *
+ * sessionKEy - 32byte buffer to store sessionKey in
+ * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match
+ */
+
+int keyUnwrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey,
+ const unsigned char *wrappedKey, unsigned char *sessionKey)
+{
+ unsigned char kek_ukm[32],cek_mac[4];
+ keyDiversifyCryptoPro(ctx,keyExchangeKey,wrappedKey
+ /* First 8 bytes of wrapped Key is ukm */
+ ,kek_ukm);
+ gost_key(ctx,kek_ukm);
+ gost_dec(ctx,wrappedKey+8,sessionKey,4);
+ gost_mac_iv(ctx,32,wrappedKey,sessionKey,32,cek_mac);
+ if (memcmp(cek_mac,wrappedKey+40,4)) {
+ return 0;
+ }
+ return 1;
+}
+
+