commit
856bbc8b35
@ -0,0 +1,2 @@ |
||||
decrypto-pro: decrypto-pro.c |
||||
gcc -o decrypto-pro decrypto-pro.c /usr/lib/`arch`-linux-gnu/engines-1.1/gost.so -lssl -lcrypto
|
@ -0,0 +1,348 @@ |
||||
// https://habrahabr.ru/post/275039/
|
||||
// Требуется либо OpenSSL 1.0.x (ГОСТ в составе), либо https://github.com/gost-engine/engine
|
||||
// Сборка:
|
||||
// 1) apt-get install libengine-gost-openssl1.1
|
||||
// 2) make
|
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include <openssl/pem.h> |
||||
#include <openssl/cms.h> |
||||
#include <openssl/err.h> |
||||
#include "gost_lcl.h" |
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000 |
||||
#define fill_GOST2001_params fill_GOST_EC_params |
||||
#define gost2001_compute_public gost_ec_compute_public |
||||
#endif |
||||
|
||||
/* Convert little-endian byte array into bignum */ |
||||
BIGNUM *reverse32bn(char *b, BN_CTX *ctx) |
||||
{ |
||||
BIGNUM *res; |
||||
char buf[32]; |
||||
BUF_reverse(buf, b, 32); |
||||
res = BN_bin2bn(buf, 32, BN_CTX_get(ctx)); |
||||
OPENSSL_cleanse(buf, sizeof(buf)); |
||||
return res; |
||||
} |
||||
|
||||
void xor_material(char *buf36, char *buf5C, char *src) |
||||
{ |
||||
int i; |
||||
for(i = 0; i < 32; i++) |
||||
{ |
||||
buf36[i] = src[i] ^ 0x36; |
||||
buf5C[i] = src[i] ^ 0x5C; |
||||
} |
||||
} |
||||
|
||||
int make_pwd_key(char *result_key, char *start12, int start12_len, char *passw) |
||||
{ |
||||
int result; |
||||
int i; |
||||
char pincode4[1024]; |
||||
int pin_len; |
||||
char current[32]; |
||||
char material36[32]; |
||||
char material5C[32]; |
||||
char hash_result[32]; |
||||
gost_hash_ctx ctx; |
||||
init_gost_hash_ctx(&ctx, &GostR3411_94_CryptoProParamSet); |
||||
memset(pincode4, 0, sizeof(pincode4)); |
||||
pin_len = strlen(passw); |
||||
if (pin_len*4 > sizeof(pincode4)) { result = 1; goto err; } |
||||
for(i = 0; i < pin_len; i++) |
||||
pincode4[i*4] = passw[i]; |
||||
|
||||
start_hash(&ctx); |
||||
hash_block(&ctx, start12, start12_len); |
||||
if (pin_len)
|
||||
hash_block(&ctx, pincode4, pin_len * 4); |
||||
finish_hash(&ctx, hash_result); |
||||
|
||||
memcpy(current, (char*)"DENEFH028.760246785.IUEFHWUIO.EF", 32); |
||||
|
||||
for(i = 0; i < (pin_len?2000:2); i++) |
||||
{ |
||||
xor_material(material36, material5C, current); |
||||
start_hash(&ctx); |
||||
hash_block(&ctx, material36, 32); |
||||
hash_block(&ctx, hash_result, 32); |
||||
hash_block(&ctx, material5C, 32); |
||||
hash_block(&ctx, hash_result, 32); |
||||
finish_hash(&ctx, current); |
||||
} |
||||
|
||||
xor_material(material36, material5C, current); |
||||
|
||||
start_hash(&ctx); |
||||
hash_block(&ctx, material36, 32); |
||||
hash_block(&ctx, start12, start12_len); |
||||
hash_block(&ctx, material5C, 32); |
||||
if (pin_len)
|
||||
hash_block(&ctx, pincode4, pin_len * 4); |
||||
finish_hash(&ctx, current); |
||||
|
||||
start_hash(&ctx); |
||||
hash_block(&ctx, current, 32); |
||||
finish_hash(&ctx, result_key); |
||||
|
||||
result = 0; //ok
|
||||
err: |
||||
return result; |
||||
} |
||||
|
||||
BIGNUM *decode_primary_key(char *pwd_key, char *primary_key, BN_CTX *bn_ctx) |
||||
{ |
||||
BIGNUM *res; |
||||
char buf[32]; |
||||
gost_ctx ctx; |
||||
gost_init(&ctx, gost_cipher_list->sblock); |
||||
gost_key(&ctx, pwd_key); |
||||
gost_dec(&ctx, primary_key, buf, 4); |
||||
res = reverse32bn(buf, bn_ctx); |
||||
OPENSSL_cleanse(buf, sizeof(buf)); |
||||
return res; |
||||
} |
||||
|
||||
BIGNUM *remove_mask_and_check_public(char *oid_param_set8, BIGNUM *key_with_mask, BIGNUM *mask, char *public8, BN_CTX *ctx) |
||||
{ |
||||
int result; |
||||
EC_KEY *eckey = NULL; |
||||
const EC_POINT *pubkey; |
||||
const EC_GROUP *group; |
||||
BIGNUM *X, *Y, *order, *raw_secret, *mask_inv; |
||||
char outbuf[32], public_X[32]; |
||||
ASN1_OBJECT *obj; |
||||
int nid; |
||||
|
||||
order = BN_CTX_get(ctx); |
||||
mask_inv = BN_CTX_get(ctx); |
||||
raw_secret = BN_CTX_get(ctx); |
||||
X = BN_CTX_get(ctx); |
||||
Y = BN_CTX_get(ctx); |
||||
if (!order || !mask_inv || !raw_secret || !X || !Y) { result = 1; goto err; } |
||||
|
||||
obj = ASN1_OBJECT_create(0, oid_param_set8+1, *oid_param_set8, NULL, NULL); |
||||
nid = OBJ_obj2nid(obj); |
||||
ASN1_OBJECT_free(obj); |
||||
|
||||
if (!(eckey = EC_KEY_new())) { result = 1; goto err; } |
||||
if (!fill_GOST2001_params(eckey, nid)) { result = 1; goto err; } |
||||
if (!(group = EC_KEY_get0_group(eckey))) { result = 1; goto err; } |
||||
if (!EC_GROUP_get_order(group, order, ctx)) { result = 1; goto err; } |
||||
|
||||
if (!BN_mod_inverse(mask_inv, mask, order, ctx)) { result = 1; goto err; } |
||||
if (!BN_mod_mul(raw_secret, key_with_mask, mask_inv, order, ctx)) { result = 1; goto err; } |
||||
|
||||
if (!EC_KEY_set_private_key(eckey, raw_secret)) { result = 1; goto err; } |
||||
if (!gost2001_compute_public(eckey)) { result = 1; goto err; } |
||||
if (!(pubkey = EC_KEY_get0_public_key(eckey))) { result = 1; goto err; } |
||||
if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { result = 1; goto err; } |
||||
|
||||
store_bignum(X, outbuf, sizeof(outbuf)); |
||||
BUF_reverse(public_X, outbuf, sizeof(outbuf)); |
||||
if (memcmp(public_X, public8, 8) != 0) { result = 1; goto err; } |
||||
|
||||
result = 0; //ok
|
||||
err: |
||||
if (eckey) EC_KEY_free(eckey); |
||||
if (result == 0) return raw_secret; |
||||
return NULL; |
||||
} |
||||
|
||||
int file_length(char *fname) |
||||
{ |
||||
int len; |
||||
FILE *f = fopen(fname, "rb"); |
||||
if (f == NULL) return -1; |
||||
fseek(f, 0, SEEK_END); |
||||
len = ftell(f); |
||||
fclose(f); |
||||
return len; |
||||
} |
||||
|
||||
int read_file(char *fname, int start_pos, char *buf, int len) |
||||
{ |
||||
int read_len; |
||||
FILE *f = fopen(fname, "rb"); |
||||
if (f == NULL) return 1; |
||||
if (start_pos) fseek(f, start_pos, SEEK_SET); |
||||
read_len = fread(buf, 1, len, f); |
||||
fclose(f); |
||||
if (read_len != len) return 1; |
||||
return 0; //ok
|
||||
} |
||||
|
||||
int get_asn1_len(unsigned char *buf, int *size_hdr) |
||||
{ |
||||
int n, i, res; |
||||
int pos = 0; |
||||
if ((buf[pos]&0x80) == 0) { |
||||
*size_hdr = 1; |
||||
return buf[pos]; |
||||
} |
||||
n = buf[pos++]&0x7f; |
||||
res = 0; |
||||
for(i = 0; i < n; i++) { |
||||
res = res*256 + buf[pos++]; |
||||
} |
||||
*size_hdr = n+1; |
||||
return res; |
||||
} |
||||
|
||||
#define MAX_HEADER 20000 |
||||
int read_container(char *fpath, int flag2, char *salt12, char *primary_key, char *masks_key, char *public8, char *oid_param_set8) |
||||
{ |
||||
int result; |
||||
char primary_path[1024+30]; |
||||
char masks_path[1024+30]; |
||||
char header_path[1024+30]; |
||||
char header_buf[MAX_HEADER]; |
||||
int header_len; |
||||
int i, len, pos, size_hdr; |
||||
|
||||
if (strlen(fpath)>1024) { result = 1; goto err; } |
||||
|
||||
sprintf(header_path, "%s/header.key", fpath); |
||||
if (flag2 == 0) |
||||
{ |
||||
sprintf(primary_path, "%s/primary.key", fpath); |
||||
sprintf(masks_path, "%s/masks.key", fpath); |
||||
} |
||||
else |
||||
{ |
||||
sprintf(primary_path, "%s/primary2.key", fpath); |
||||
sprintf(masks_path, "%s/masks2.key", fpath); |
||||
} |
||||
|
||||
if (read_file(primary_path, 4, primary_key, 32)) { result = 1; goto err; } |
||||
if (read_file(masks_path, 4, masks_key, 32)) { result = 1; goto err; } |
||||
if (read_file(masks_path, 0x26, salt12, 12)) { result = 1; goto err; } |
||||
|
||||
header_len = file_length(header_path); |
||||
if (header_len < 0x42 || header_len > MAX_HEADER) { result = 1; goto err; } |
||||
if (read_file(header_path, 0, header_buf, header_len)) { result = 1; goto err; } |
||||
|
||||
//------------- skip certificate ---------------------------
|
||||
pos = 0; |
||||
for(i = 0; i < 2; i++) |
||||
{ |
||||
get_asn1_len(header_buf+pos+1, &size_hdr); |
||||
pos += size_hdr+1; |
||||
if (pos > header_len-8) { result = 2; goto err; } |
||||
} |
||||
|
||||
//------------------ get oid_param_set8 -----------------------
|
||||
#define PARAM_SET_POS 34 |
||||
if (memcmp(header_buf+pos+PARAM_SET_POS, "\x6\x7", 2) != 0) { result = 2; goto err; } |
||||
memcpy(oid_param_set8, header_buf+pos+PARAM_SET_POS+1, 8); |
||||
|
||||
//------------------ get public8 -----------------------
|
||||
result = 2; //not found
|
||||
pos += 52; |
||||
for(i = 0; i < 3; i++) |
||||
{ |
||||
len = get_asn1_len(header_buf+pos+1, &size_hdr); |
||||
if (len == 8 && memcmp(header_buf+pos, "\x8a\x8", 2) == 0) |
||||
{ |
||||
memcpy(public8,header_buf+pos+2,8); |
||||
result = 0; //ok
|
||||
break; |
||||
} |
||||
pos += len+size_hdr+1; |
||||
if (pos > header_len-8) { result = 2; goto err; } |
||||
} |
||||
err: |
||||
OPENSSL_cleanse(header_buf, sizeof(header_buf)); |
||||
return result; |
||||
} |
||||
|
||||
#define START_OID 0x12 |
||||
#define START_KEY 0x28 |
||||
unsigned char asn1_private_key[72] = { |
||||
0x30,0x46,2,1,0,0x30,0x1c,6,6,0x2a,0x85,3,2,2,0x13,0x30,0x12,6,7,0x11, |
||||
0x11,0x11,0x11,0x11,0x11,0x11,6,7,0x2a,0x85,3,2,2,0x1e,1,4,0x23,2,0x21,0 |
||||
}; |
||||
|
||||
int main(int argc, char **argv) |
||||
{ |
||||
int result; |
||||
char *container_path; |
||||
char *passw; |
||||
char salt12[12]; |
||||
char primary_key[32]; |
||||
char masks_key[32]; |
||||
char public8[8]; |
||||
char oid_param_set8[8]; |
||||
BN_CTX *ctx; |
||||
BIGNUM *key_with_mask; |
||||
BIGNUM *mask; |
||||
BIGNUM *raw_key; |
||||
char pwd_key[32]; |
||||
char outbuf[32]; |
||||
|
||||
ctx = BN_CTX_new(); |
||||
|
||||
if (argc == 2) |
||||
{ |
||||
container_path = argv[1]; |
||||
passw = ""; |
||||
} |
||||
else |
||||
if (argc == 3) |
||||
{ |
||||
container_path = argv[1]; |
||||
passw = argv[2]; |
||||
} |
||||
else |
||||
{ |
||||
printf("get_private container_path [passw]\n"); |
||||
result = 1; |
||||
goto err; |
||||
} |
||||
|
||||
if (read_container(container_path, 0, salt12, primary_key, masks_key, public8, oid_param_set8) != 0 && |
||||
read_container(container_path, 1, salt12, primary_key, masks_key, public8, oid_param_set8) != 0) |
||||
{ |
||||
printf("can not read container from %s\n", container_path); |
||||
result = 2; |
||||
goto err; |
||||
} |
||||
|
||||
make_pwd_key(pwd_key, salt12, 12, passw); |
||||
key_with_mask = decode_primary_key(pwd_key, primary_key, ctx); |
||||
OPENSSL_cleanse(pwd_key, sizeof(pwd_key)); |
||||
mask = reverse32bn(masks_key, ctx); |
||||
raw_key = remove_mask_and_check_public(oid_param_set8, key_with_mask, mask, public8, ctx); |
||||
|
||||
if (raw_key) |
||||
{ |
||||
BIO *bio; |
||||
store_bignum(raw_key, outbuf, sizeof(outbuf)); |
||||
memcpy(asn1_private_key+START_OID, oid_param_set8, 8); |
||||
memcpy(asn1_private_key+START_KEY, outbuf, 32); |
||||
//bio = BIO_new_file("private.key", "w");
|
||||
bio = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); |
||||
PEM_write_bio(bio, "PRIVATE KEY", "", asn1_private_key, sizeof(asn1_private_key)); |
||||
BIO_free(bio); |
||||
OPENSSL_cleanse(outbuf, sizeof(outbuf)); |
||||
OPENSSL_cleanse(asn1_private_key, sizeof(asn1_private_key)); |
||||
result = 0; //ok
|
||||
} |
||||
else |
||||
{ |
||||
printf("Error check public key\n"); |
||||
result = 3; |
||||
} |
||||
|
||||
err: |
||||
BN_CTX_free(ctx); |
||||
OPENSSL_cleanse(salt12, sizeof(salt12)); |
||||
OPENSSL_cleanse(primary_key, sizeof(primary_key)); |
||||
OPENSSL_cleanse(masks_key, sizeof(masks_key)); |
||||
return result; |
||||
} |
@ -0,0 +1,110 @@ |
||||
/**********************************************************************
|
||||
* gost89.h * |
||||
* Copyright (c) 2005-2006 Cryptocom LTD * |
||||
* This file is distributed under the same license as OpenSSL * |
||||
* * |
||||
* Declarations for GOST 28147-89 encryption algorithm * |
||||
* No OpenSSL libraries required to compile and use * |
||||
* this code * |
||||
**********************************************************************/ |
||||
#ifndef GOST89_H |
||||
# define GOST89_H |
||||
|
||||
/* Typedef for unsigned 32-bit integer */ |
||||
# if __LONG_MAX__ > 2147483647L |
||||
typedef unsigned int u4; |
||||
# else |
||||
typedef unsigned long u4; |
||||
# endif |
||||
/* Typedef for unsigned 8-bit integer */ |
||||
typedef unsigned char byte; |
||||
|
||||
/* Internal representation of GOST substitution blocks */ |
||||
typedef struct { |
||||
byte k8[16]; |
||||
byte k7[16]; |
||||
byte k6[16]; |
||||
byte k5[16]; |
||||
byte k4[16]; |
||||
byte k3[16]; |
||||
byte k2[16]; |
||||
byte k1[16]; |
||||
} gost_subst_block; |
||||
|
||||
/* Cipher context includes key and preprocessed substitution block */ |
||||
typedef struct { |
||||
u4 master_key[8]; |
||||
u4 key[8]; |
||||
u4 mask[8]; |
||||
/* Constant s-boxes -- set up in gost_init(). */ |
||||
u4 k87[256], k65[256], k43[256], k21[256]; |
||||
} gost_ctx; |
||||
/*
|
||||
* Note: encrypt and decrypt expect full blocks--padding blocks is caller's |
||||
* responsibility. All bulk encryption is done in ECB mode by these calls. |
||||
* Other modes may be added easily enough. |
||||
*/ |
||||
/* Encrypt several full blocks in ECB mode */ |
||||
void gost_enc(gost_ctx * c, const byte * clear, byte * cipher, int blocks); |
||||
/* Decrypt several full blocks in ECB mode */ |
||||
void gost_dec(gost_ctx * c, const byte * cipher, byte * clear, int blocks); |
||||
/* Encrypts several full blocks in CFB mode using 8byte IV */ |
||||
void gost_enc_cfb(gost_ctx * ctx, const byte * iv, const byte * clear, |
||||
byte * cipher, int blocks); |
||||
/* Decrypts several full blocks in CFB mode using 8byte IV */ |
||||
void gost_dec_cfb(gost_ctx * ctx, const byte * iv, const byte * cipher, |
||||
byte * clear, int blocks); |
||||
|
||||
/* Encrypt one block */ |
||||
void gostcrypt(gost_ctx * c, const byte * in, byte * out); |
||||
/* Decrypt one block */ |
||||
void gostdecrypt(gost_ctx * c, const byte * in, byte * out); |
||||
/* Set key into context */ |
||||
void gost_key(gost_ctx * c, const byte * k); |
||||
/* Set key into context without key mask */ |
||||
void gost_key_nomask(gost_ctx * c, const byte * k); |
||||
/* Set key into context */ |
||||
void magma_key(gost_ctx * c, const byte * k); |
||||
/* Set master 256-bit key to be used in TLSTREE calculation into context */ |
||||
void magma_master_key(gost_ctx *c, const byte *k); |
||||
/* Get key from context */ |
||||
void gost_get_key(gost_ctx * c, byte * k); |
||||
/* Set S-blocks into context */ |
||||
void gost_init(gost_ctx * c, const gost_subst_block * b); |
||||
/* Clean up context */ |
||||
void gost_destroy(gost_ctx * c); |
||||
/* Intermediate function used for calculate hash */ |
||||
void gost_enc_with_key(gost_ctx *, byte * key, byte * inblock, |
||||
byte * outblock); |
||||
/* Compute MAC of given length in bits from data */ |
||||
int gost_mac(gost_ctx * ctx, int mac_len, const unsigned char *data, |
||||
unsigned int data_len, unsigned char *mac); |
||||
/*
|
||||
* Compute MAC of given length in bits from data, using non-zero 8-byte IV |
||||
* (non-standard, for use in CryptoPro key transport only |
||||
*/ |
||||
int gost_mac_iv(gost_ctx * ctx, int mac_len, const unsigned char *iv, |
||||
const unsigned char *data, unsigned int data_len, |
||||
unsigned char *mac); |
||||
/* Perform one step of MAC calculation like gostcrypt */ |
||||
void mac_block(gost_ctx * c, byte * buffer, const byte * block); |
||||
/* Extracts MAC value from mac state buffer */ |
||||
void get_mac(byte * buffer, int nbits, byte * out); |
||||
/* Implements cryptopro key meshing algorithm. Expect IV to be 8-byte size*/ |
||||
void cryptopro_key_meshing(gost_ctx * ctx, unsigned char *iv); |
||||
/* Parameter sets specified in RFC 4357 */ |
||||
extern gost_subst_block GostR3411_94_TestParamSet; |
||||
extern gost_subst_block GostR3411_94_CryptoProParamSet; |
||||
extern gost_subst_block Gost28147_TestParamSet; |
||||
extern gost_subst_block Gost28147_CryptoProParamSetA; |
||||
extern gost_subst_block Gost28147_CryptoProParamSetB; |
||||
extern gost_subst_block Gost28147_CryptoProParamSetC; |
||||
extern gost_subst_block Gost28147_CryptoProParamSetD; |
||||
extern gost_subst_block Gost28147_TC26ParamSetZ; |
||||
extern const byte CryptoProKeyMeshingKey[]; |
||||
typedef unsigned int word32; |
||||
/* For tests. */ |
||||
void kboxinit(gost_ctx * c, const gost_subst_block * b); |
||||
void magma_get_key(gost_ctx * c, byte * k); |
||||
void acpkm_magma_key_meshing(gost_ctx * ctx); |
||||
#endif |
@ -0,0 +1,257 @@ |
||||
#ifndef GOST_TOOLS_H |
||||
# define GOST_TOOLS_H |
||||
/**********************************************************************
|
||||
* gost_lcl.h * |
||||
* Copyright (c) 2006 Cryptocom LTD * |
||||
* This file is distributed under the same license as OpenSSL * |
||||
* * |
||||
* Internal declarations used in GOST engine * |
||||
* OpenSSL 0.9.9 libraries required to compile and use * |
||||
* this code * |
||||
**********************************************************************/ |
||||
# include <openssl/bn.h> |
||||
# include <openssl/evp.h> |
||||
# include <openssl/dsa.h> |
||||
# include <openssl/asn1t.h> |
||||
# include <openssl/x509.h> |
||||
# include <openssl/engine.h> |
||||
# include <openssl/ec.h> |
||||
# include "gost89.h" |
||||
# include "gosthash.h" |
||||
/* Control commands */ |
||||
# define GOST_PARAM_CRYPT_PARAMS 0 |
||||
# define GOST_PARAM_PBE_PARAMS 1 |
||||
# define GOST_PARAM_MAX 1 |
||||
# define GOST_CTRL_CRYPT_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_CRYPT_PARAMS) |
||||
# define GOST_CTRL_PBE_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_PBE_PARAMS) |
||||
|
||||
typedef struct R3410_ec { |
||||
int nid; |
||||
char *a; |
||||
char *b; |
||||
char *p; |
||||
char *q; |
||||
char *x; |
||||
char *y; |
||||
char *cofactor; |
||||
} R3410_ec_params; |
||||
|
||||
extern R3410_ec_params R3410_2001_paramset[], |
||||
*R3410_2012_256_paramset, R3410_2012_512_paramset[]; |
||||
|
||||
extern const ENGINE_CMD_DEFN gost_cmds[]; |
||||
int gost_control_func(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); |
||||
const char *get_gost_engine_param(int param); |
||||
int gost_set_default_param(int param, const char *value); |
||||
void gost_param_free(void); |
||||
|
||||
/* method registration */ |
||||
|
||||
int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth, |
||||
const char *pemstr, const char *info); |
||||
int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags); |
||||
|
||||
/* Gost-specific pmeth control-function parameters */ |
||||
/* For GOST R34.10 parameters */ |
||||
# define param_ctrl_string "paramset" |
||||
# define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1) |
||||
/* For GOST 28147 MAC */ |
||||
# define key_ctrl_string "key" |
||||
# define hexkey_ctrl_string "hexkey" |
||||
# define maclen_ctrl_string "size" |
||||
# define EVP_PKEY_CTRL_GOST_MAC_HEXKEY (EVP_PKEY_ALG_CTRL+3) |
||||
# define EVP_PKEY_CTRL_MAC_LEN (EVP_PKEY_ALG_CTRL+5) |
||||
/* Pmeth internal representation */ |
||||
struct gost_pmeth_data { |
||||
int sign_param_nid; /* Should be set whenever parameters are
|
||||
* filled */ |
||||
EVP_MD *md; |
||||
unsigned char *shared_ukm; |
||||
int peer_key_used; |
||||
}; |
||||
|
||||
struct gost_mac_pmeth_data { |
||||
short int key_set; |
||||
short int mac_size; |
||||
int mac_param_nid; |
||||
EVP_MD *md; |
||||
unsigned char key[32]; |
||||
}; |
||||
|
||||
struct gost_mac_key { |
||||
int mac_param_nid; |
||||
unsigned char key[32]; |
||||
short int mac_size; |
||||
}; |
||||
/* GOST-specific ASN1 structures */ |
||||
|
||||
typedef struct { |
||||
ASN1_OCTET_STRING *encrypted_key; |
||||
ASN1_OCTET_STRING *imit; |
||||
} GOST_KEY_INFO; |
||||
|
||||
DECLARE_ASN1_FUNCTIONS(GOST_KEY_INFO) |
||||
|
||||
typedef struct { |
||||
ASN1_OBJECT *cipher; |
||||
X509_PUBKEY *ephem_key; |
||||
ASN1_OCTET_STRING *eph_iv; |
||||
} GOST_KEY_AGREEMENT_INFO; |
||||
|
||||
DECLARE_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO) |
||||
|
||||
typedef struct { |
||||
GOST_KEY_INFO *key_info; |
||||
GOST_KEY_AGREEMENT_INFO *key_agreement_info; |
||||
} GOST_KEY_TRANSPORT; |
||||
|
||||
DECLARE_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT) |
||||
|
||||
typedef struct { /* FIXME incomplete */ |
||||
GOST_KEY_TRANSPORT *gkt; |
||||
} GOST_CLIENT_KEY_EXCHANGE_PARAMS; |
||||
|
||||
/*
|
||||
* Hacks to shorten symbols to 31 characters or less, or OpenVMS. This mimics |
||||
* what's done in symhacks.h, but since this is a very local header file, I |
||||
* prefered to put this hack directly here. -- Richard Levitte |
||||
*/ |
||||
# ifdef OPENSSL_SYS_VMS |
||||
# undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_it |
||||
# define GOST_CLIENT_KEY_EXCHANGE_PARAMS_it GOST_CLIENT_KEY_EXC_PARAMS_it |
||||
# undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_new |
||||
# define GOST_CLIENT_KEY_EXCHANGE_PARAMS_new GOST_CLIENT_KEY_EXC_PARAMS_new |
||||
# undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_free |
||||
# define GOST_CLIENT_KEY_EXCHANGE_PARAMS_free GOST_CLIENT_KEY_EXC_PARAMS_free |
||||
# undef d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS |
||||
# define d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS d2i_GOST_CLIENT_KEY_EXC_PARAMS |
||||
# undef i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS |
||||
# define i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS i2d_GOST_CLIENT_KEY_EXC_PARAMS |
||||
# endif /* End of hack */ |
||||
DECLARE_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS) |
||||
typedef struct { |
||||
ASN1_OBJECT *key_params; |
||||
ASN1_OBJECT *hash_params; |
||||
ASN1_OBJECT *cipher_params; |
||||
} GOST_KEY_PARAMS; |
||||
|
||||
DECLARE_ASN1_FUNCTIONS(GOST_KEY_PARAMS) |
||||
|
||||
typedef struct { |
||||
ASN1_OCTET_STRING *iv; |
||||
ASN1_OBJECT *enc_param_set; |
||||
} GOST_CIPHER_PARAMS; |
||||
|
||||
DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS) |
||||
|
||||
typedef struct { |
||||
ASN1_OCTET_STRING *masked_priv_key; |
||||
ASN1_OCTET_STRING *public_key; |
||||
} MASKED_GOST_KEY; |
||||
|
||||
DECLARE_ASN1_FUNCTIONS(MASKED_GOST_KEY) |
||||
|
||||
/*============== Message digest and cipher related structures ==========*/ |
||||
/*
|
||||
* Structure used as EVP_MD_CTX-md_data. It allows to avoid storing |
||||
* in the md-data pointers to dynamically allocated memory. I |
||||
* cannot invent better way to avoid memory leaks, because openssl |
||||
* insist on invoking Init on Final-ed digests, and there is no |
||||
* reliable way to find out whether pointer in the passed md_data is |
||||
* valid or not. |
||||
*/ |
||||
struct ossl_gost_digest_ctx { |
||||
gost_hash_ctx dctx; |
||||
gost_ctx cctx; |
||||
}; |
||||
/* EVP_MD structure for GOST R 34.11 */ |
||||
EVP_MD *digest_gost(void); |
||||
void digest_gost_destroy(void); |
||||
/* EVP MD structure for GOST R 34.11-2012 algorithms */ |
||||
EVP_MD *digest_gost2012_256(void); |
||||
EVP_MD *digest_gost2012_512(void); |
||||
void digest_gost2012_256_destroy(void); |
||||
void digest_gost2012_512_destroy(void); |
||||
/* EVP_MD structure for GOST 28147 in MAC mode */ |
||||
EVP_MD *imit_gost_cpa(void); |
||||
void imit_gost_cpa_destroy(void); |
||||
EVP_MD *imit_gost_cp_12(void); |
||||
void imit_gost_cp_12_destroy(void); |
||||
/* Cipher context used for EVP_CIPHER operation */ |
||||
struct ossl_gost_cipher_ctx { |
||||
int paramNID; |
||||
unsigned int count; |
||||
int key_meshing; |
||||
gost_ctx cctx; |
||||
}; |
||||
/* Structure to map parameter NID to S-block */ |
||||
struct gost_cipher_info { |
||||
int nid; |
||||
gost_subst_block *sblock; |
||||
int key_meshing; |
||||
}; |
||||
/* Context for MAC */ |
||||
struct ossl_gost_imit_ctx { |
||||
gost_ctx cctx; |
||||
unsigned char buffer[8]; |
||||
unsigned char partial_block[8]; |
||||
unsigned int count; |
||||
int key_meshing; |
||||
int bytes_left; |
||||
int key_set; |
||||
int dgst_size; |
||||
}; |
||||
/* Table which maps parameter NID to S-blocks */ |
||||
extern struct gost_cipher_info gost_cipher_list[]; |
||||
/* Find encryption params from ASN1_OBJECT */ |
||||
const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj); |
||||
/* Implementation of GOST 28147-89 cipher in CFB and CNT modes */ |
||||
const EVP_CIPHER *cipher_gost(); |
||||
const EVP_CIPHER *cipher_gost_cbc(); |
||||
const EVP_CIPHER *cipher_gost_cpacnt(); |
||||
const EVP_CIPHER *cipher_gost_cpcnt_12(); |
||||
void cipher_gost_destroy(); |
||||
# define EVP_MD_CTRL_KEY_LEN (EVP_MD_CTRL_ALG_CTRL+3) |
||||
# define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+4) |
||||
# define EVP_MD_CTRL_MAC_LEN (EVP_MD_CTRL_ALG_CTRL+5) |
||||
/* EVP_PKEY_METHOD key encryption callbacks */ |
||||
/* From gost_ec_keyx.c */ |
||||
int pkey_GOST_ECcp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, |
||||
size_t *outlen, const unsigned char *key, |
||||
size_t key_len); |
||||
|
||||
int pkey_GOST_ECcp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, |
||||
size_t *outlen, const unsigned char *in, |
||||
size_t in_len); |
||||
/* derive functions */ |
||||
/* From gost_ec_keyx.c */ |
||||
int pkey_gost_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, |
||||
size_t *keylen); |
||||
int fill_GOST_EC_params(EC_KEY *eckey, int nid); |
||||
int gost_sign_keygen(DSA *dsa); |
||||
int gost_ec_keygen(EC_KEY *ec); |
||||
|
||||
DSA_SIG *gost_ec_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey); |
||||
|
||||
int gost_do_verify(const unsigned char *dgst, int dgst_len, |
||||
DSA_SIG *sig, DSA *dsa); |
||||
int gost_ec_verify(const unsigned char *dgst, int dgst_len, |
||||
DSA_SIG *sig, EC_KEY *ec); |
||||
int gost_ec_compute_public(EC_KEY *ec); |
||||
/*============== miscellaneous functions============================= */ |
||||
/* from gost_sign.c */ |
||||
/* Convert GOST R 34.11 hash sum to bignum according to standard */ |
||||
BIGNUM *hashsum2bn(const unsigned char *dgst, int len); |
||||
/*
|
||||
* Store bignum in byte array of given length, prepending by zeros if |
||||
* nesseccary |
||||
*/ |
||||
int store_bignum(const BIGNUM *bn, unsigned char *buf, int len); |
||||
/* Pack GOST R 34.10 signature according to CryptoPro rules */ |
||||
int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen); |
||||
/* from ameth.c */ |
||||
/* Get private key as BIGNUM from both 34.10-2001 keys*/ |
||||
/* Returns pointer into EVP_PKEY structure */ |
||||
BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey); |
||||
|
||||
#endif |
@ -0,0 +1,52 @@ |
||||
/**********************************************************************
|
||||
* gosthash.h * |
||||
* Copyright (c) 2005-2006 Cryptocom LTD * |
||||
* This file is distributed under the same license as OpenSSL * |
||||
* * |
||||
* Declaration of GOST R 34.11-94 hash functions * |
||||
* uses and gost89.h Doesn't need OpenSSL * |
||||
**********************************************************************/ |
||||
#ifndef GOSTHASH_H |
||||
# define GOSTHASH_H |
||||
# include "gost89.h" |
||||
# include <stdlib.h> |
||||
|
||||
# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) |
||||
typedef __int64 ghosthash_len; |
||||
# elif defined(__arch64__) |
||||
typedef long ghosthash_len; |
||||
# else |
||||
typedef long long ghosthash_len; |
||||
# endif |
||||
|
||||
typedef struct gost_hash_ctx { |
||||
ghosthash_len len; |
||||
gost_ctx *cipher_ctx; |
||||
int left; |
||||
byte H[32]; |
||||
byte S[32]; |
||||
byte remainder[32]; |
||||
} gost_hash_ctx; |
||||
|
||||
/* Initalizes gost hash ctx, including creation of gost cipher ctx */ |
||||
|
||||
int init_gost_hash_ctx(gost_hash_ctx * ctx, |
||||
const gost_subst_block * subst_block); |
||||
void done_gost_hash_ctx(gost_hash_ctx * ctx); |
||||
|
||||
/*
|
||||
* Cleans up all fields, except cipher ctx preparing ctx for computing of new |
||||
* hash value |
||||
*/ |
||||
int start_hash(gost_hash_ctx * ctx); |
||||
|
||||
/* Hashes block of data */ |
||||
int hash_block(gost_hash_ctx * ctx, const byte * block, size_t length); |
||||
|
||||
/*
|
||||
* Finalizes computation of hash and fills buffer (which should be at least |
||||
* 32 bytes long) with value of computed hash. |
||||
*/ |
||||
int finish_hash(gost_hash_ctx * ctx, byte * hashval); |
||||
|
||||
#endif |
Loading…
Reference in new issue