gost_eng.c revision 238384
1238384Sjkim/********************************************************************** 2238384Sjkim * gost_eng.c * 3238384Sjkim * Copyright (c) 2005-2006 Cryptocom LTD * 4238384Sjkim * This file is distributed under the same license as OpenSSL * 5238384Sjkim * * 6238384Sjkim * Main file of GOST engine * 7238384Sjkim * for OpenSSL * 8238384Sjkim * Requires OpenSSL 0.9.9 for compilation * 9238384Sjkim **********************************************************************/ 10238384Sjkim#include <string.h> 11238384Sjkim#include <openssl/crypto.h> 12238384Sjkim#include <openssl/err.h> 13238384Sjkim#include <openssl/evp.h> 14238384Sjkim#include <openssl/engine.h> 15238384Sjkim#include <openssl/obj_mac.h> 16238384Sjkim#include "e_gost_err.h" 17238384Sjkim#include "gost_lcl.h" 18238384Sjkimstatic const char *engine_gost_id = "gost"; 19238384Sjkimstatic const char *engine_gost_name = "Reference implementation of GOST engine"; 20238384Sjkim 21238384Sjkim/* Symmetric cipher and digest function registrar */ 22238384Sjkim 23238384Sjkimstatic int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 24238384Sjkim const int **nids, int nid); 25238384Sjkim 26238384Sjkimstatic int gost_digests(ENGINE *e, const EVP_MD **digest, 27238384Sjkim const int **nids, int ind); 28238384Sjkim 29238384Sjkimstatic int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, 30238384Sjkim const int **nids, int nid); 31238384Sjkim 32238384Sjkimstatic int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, 33238384Sjkim const int **nids, int nid); 34238384Sjkim 35238384Sjkimstatic int gost_cipher_nids[] = 36238384Sjkim {NID_id_Gost28147_89, NID_gost89_cnt,0}; 37238384Sjkim 38238384Sjkimstatic int gost_digest_nids[] = 39238384Sjkim {NID_id_GostR3411_94,NID_id_Gost28147_89_MAC, 0}; 40238384Sjkim 41238384Sjkimstatic int gost_pkey_meth_nids[] = 42238384Sjkim {NID_id_GostR3410_94, 43238384Sjkim NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0}; 44238384Sjkim 45238384Sjkimstatic EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL, 46238384Sjkim *pmeth_GostR3410_2001 = NULL, 47238384Sjkim *pmeth_Gost28147_MAC = NULL; 48238384Sjkim 49238384Sjkimstatic EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL, 50238384Sjkim *ameth_GostR3410_2001 = NULL, 51238384Sjkim *ameth_Gost28147_MAC = NULL; 52238384Sjkim 53238384Sjkim 54238384Sjkimstatic int gost_engine_init(ENGINE *e) 55238384Sjkim { 56238384Sjkim return 1; 57238384Sjkim } 58238384Sjkim 59238384Sjkimstatic int gost_engine_finish(ENGINE *e) 60238384Sjkim { 61238384Sjkim return 1; 62238384Sjkim } 63238384Sjkim 64238384Sjkimstatic int gost_engine_destroy(ENGINE *e) 65238384Sjkim { 66238384Sjkim gost_param_free(); 67238384Sjkim return 1; 68238384Sjkim } 69238384Sjkim 70238384Sjkimstatic int bind_gost (ENGINE *e,const char *id) 71238384Sjkim { 72238384Sjkim int ret = 0; 73238384Sjkim if (id && strcmp(id, engine_gost_id)) return 0; 74238384Sjkim 75238384Sjkim if (!ENGINE_set_id(e, engine_gost_id)) 76238384Sjkim { 77238384Sjkim printf("ENGINE_set_id failed\n"); 78238384Sjkim goto end; 79238384Sjkim } 80238384Sjkim if (!ENGINE_set_name(e, engine_gost_name)) 81238384Sjkim { 82238384Sjkim printf("ENGINE_set_name failed\n"); 83238384Sjkim goto end; 84238384Sjkim } 85238384Sjkim if (!ENGINE_set_digests(e, gost_digests)) 86238384Sjkim { 87238384Sjkim printf("ENGINE_set_digests failed\n"); 88238384Sjkim goto end; 89238384Sjkim } 90238384Sjkim if (! ENGINE_set_ciphers(e, gost_ciphers)) 91238384Sjkim { 92238384Sjkim printf("ENGINE_set_ciphers failed\n"); 93238384Sjkim goto end; 94238384Sjkim } 95238384Sjkim if (! ENGINE_set_pkey_meths(e, gost_pkey_meths)) 96238384Sjkim { 97238384Sjkim printf("ENGINE_set_pkey_meths failed\n"); 98238384Sjkim goto end; 99238384Sjkim } 100238384Sjkim if (! ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) 101238384Sjkim { 102238384Sjkim printf("ENGINE_set_pkey_asn1_meths failed\n"); 103238384Sjkim goto end; 104238384Sjkim } 105238384Sjkim /* Control function and commands */ 106238384Sjkim if (!ENGINE_set_cmd_defns(e,gost_cmds)) 107238384Sjkim { 108238384Sjkim fprintf(stderr,"ENGINE_set_cmd_defns failed\n"); 109238384Sjkim goto end; 110238384Sjkim } 111238384Sjkim if (!ENGINE_set_ctrl_function(e,gost_control_func)) 112238384Sjkim { 113238384Sjkim fprintf(stderr,"ENGINE_set_ctrl_func failed\n"); 114238384Sjkim goto end; 115238384Sjkim } 116238384Sjkim if ( ! ENGINE_set_destroy_function(e, gost_engine_destroy) 117238384Sjkim || ! ENGINE_set_init_function(e,gost_engine_init) 118238384Sjkim || ! ENGINE_set_finish_function(e,gost_engine_finish)) 119238384Sjkim { 120238384Sjkim goto end; 121238384Sjkim } 122238384Sjkim 123238384Sjkim if (!register_ameth_gost(NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", "GOST R 34.10-94")) goto end; 124238384Sjkim if (!register_ameth_gost(NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", "GOST R 34.10-2001")) goto end; 125238384Sjkim if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC, 126238384Sjkim "GOST-MAC", "GOST 28147-89 MAC")) goto end; 127238384Sjkim 128238384Sjkim if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) goto end; 129238384Sjkim if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) goto end; 130238384Sjkim if (!register_pmeth_gost(NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0)) 131238384Sjkim goto end; 132238384Sjkim if ( ! ENGINE_register_ciphers(e) 133238384Sjkim || ! ENGINE_register_digests(e) 134238384Sjkim || ! ENGINE_register_pkey_meths(e) 135238384Sjkim /* These two actually should go in LIST_ADD command */ 136238384Sjkim || ! EVP_add_cipher(&cipher_gost) 137238384Sjkim || ! EVP_add_cipher(&cipher_gost_cpacnt) 138238384Sjkim || ! EVP_add_digest(&digest_gost) 139238384Sjkim || ! EVP_add_digest(&imit_gost_cpa) 140238384Sjkim ) 141238384Sjkim { 142238384Sjkim goto end; 143238384Sjkim } 144238384Sjkim 145238384Sjkim ERR_load_GOST_strings(); 146238384Sjkim ret = 1; 147238384Sjkim end: 148238384Sjkim return ret; 149238384Sjkim } 150238384Sjkim 151238384Sjkim#ifndef OPENSSL_NO_DYNAMIC_ENGINE 152238384SjkimIMPLEMENT_DYNAMIC_BIND_FN(bind_gost) 153238384SjkimIMPLEMENT_DYNAMIC_CHECK_FN() 154238384Sjkim#endif /* ndef OPENSSL_NO_DYNAMIC_ENGINE */ 155238384Sjkim 156238384Sjkimstatic int gost_digests(ENGINE *e, const EVP_MD **digest, 157238384Sjkim const int **nids, int nid) 158238384Sjkim { 159238384Sjkim int ok =1 ; 160238384Sjkim if (!digest) 161238384Sjkim { 162238384Sjkim *nids = gost_digest_nids; 163238384Sjkim return 2; 164238384Sjkim } 165238384Sjkim /*printf("Digest no %d requested\n",nid);*/ 166238384Sjkim if(nid == NID_id_GostR3411_94) 167238384Sjkim { 168238384Sjkim *digest = &digest_gost; 169238384Sjkim } 170238384Sjkim else if (nid == NID_id_Gost28147_89_MAC) 171238384Sjkim { 172238384Sjkim *digest = &imit_gost_cpa; 173238384Sjkim } 174238384Sjkim else 175238384Sjkim { 176238384Sjkim ok =0; 177238384Sjkim *digest = NULL; 178238384Sjkim } 179238384Sjkim return ok; 180238384Sjkim } 181238384Sjkim 182238384Sjkimstatic int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher, 183238384Sjkim const int **nids, int nid) 184238384Sjkim { 185238384Sjkim int ok = 1; 186238384Sjkim if (!cipher) 187238384Sjkim { 188238384Sjkim *nids = gost_cipher_nids; 189238384Sjkim return 2; /* two ciphers are supported */ 190238384Sjkim } 191238384Sjkim 192238384Sjkim if(nid == NID_id_Gost28147_89) 193238384Sjkim { 194238384Sjkim *cipher = &cipher_gost; 195238384Sjkim } 196238384Sjkim else if (nid == NID_gost89_cnt) 197238384Sjkim { 198238384Sjkim *cipher = &cipher_gost_cpacnt; 199238384Sjkim } 200238384Sjkim else 201238384Sjkim { 202238384Sjkim ok = 0; 203238384Sjkim *cipher = NULL; 204238384Sjkim } 205238384Sjkim return ok; 206238384Sjkim } 207238384Sjkim 208238384Sjkimstatic int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, 209238384Sjkim const int **nids, int nid) 210238384Sjkim { 211238384Sjkim if (!pmeth) 212238384Sjkim { 213238384Sjkim *nids = gost_pkey_meth_nids; 214238384Sjkim return 3; 215238384Sjkim } 216238384Sjkim 217238384Sjkim switch (nid) 218238384Sjkim { 219238384Sjkim case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1; 220238384Sjkim case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1; 221238384Sjkim case NID_id_Gost28147_89_MAC: *pmeth = pmeth_Gost28147_MAC; return 1; 222238384Sjkim default:; 223238384Sjkim } 224238384Sjkim 225238384Sjkim *pmeth = NULL; 226238384Sjkim return 0; 227238384Sjkim } 228238384Sjkim 229238384Sjkimstatic int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, 230238384Sjkim const int **nids, int nid) 231238384Sjkim { 232238384Sjkim if (!ameth) 233238384Sjkim { 234238384Sjkim *nids = gost_pkey_meth_nids; 235238384Sjkim return 3; 236238384Sjkim } 237238384Sjkim switch (nid) 238238384Sjkim { 239238384Sjkim case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1; 240238384Sjkim case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1; 241238384Sjkim case NID_id_Gost28147_89_MAC: *ameth = ameth_Gost28147_MAC; return 1; 242238384Sjkim 243238384Sjkim default:; 244238384Sjkim } 245238384Sjkim 246238384Sjkim *ameth = NULL; 247238384Sjkim return 0; 248238384Sjkim } 249238384Sjkim 250238384Sjkim#ifdef OPENSSL_NO_DYNAMIC_ENGINE 251238384Sjkimstatic ENGINE *engine_gost(void) 252238384Sjkim { 253238384Sjkim ENGINE *ret = ENGINE_new(); 254238384Sjkim if (!ret) 255238384Sjkim return NULL; 256238384Sjkim if (!bind_gost(ret,engine_gost_id)) 257238384Sjkim { 258238384Sjkim ENGINE_free(ret); 259238384Sjkim return NULL; 260238384Sjkim } 261238384Sjkim return ret; 262238384Sjkim } 263238384Sjkim 264238384Sjkimvoid ENGINE_load_gost(void) 265238384Sjkim { 266238384Sjkim ENGINE *toadd =engine_gost(); 267238384Sjkim if (!toadd) return; 268238384Sjkim ENGINE_add(toadd); 269238384Sjkim ENGINE_free(toadd); 270238384Sjkim ERR_clear_error(); 271238384Sjkim } 272238384Sjkim#endif 273238384Sjkim 274