gost_eng.c revision 238384
1/********************************************************************** 2 * gost_eng.c * 3 * Copyright (c) 2005-2006 Cryptocom LTD * 4 * This file is distributed under the same license as OpenSSL * 5 * * 6 * Main file of GOST engine * 7 * for OpenSSL * 8 * Requires OpenSSL 0.9.9 for compilation * 9 **********************************************************************/ 10#include <string.h> 11#include <openssl/crypto.h> 12#include <openssl/err.h> 13#include <openssl/evp.h> 14#include <openssl/engine.h> 15#include <openssl/obj_mac.h> 16#include "e_gost_err.h" 17#include "gost_lcl.h" 18static const char *engine_gost_id = "gost"; 19static const char *engine_gost_name = "Reference implementation of GOST engine"; 20 21/* Symmetric cipher and digest function registrar */ 22 23static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 24 const int **nids, int nid); 25 26static int gost_digests(ENGINE *e, const EVP_MD **digest, 27 const int **nids, int ind); 28 29static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, 30 const int **nids, int nid); 31 32static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, 33 const int **nids, int nid); 34 35static int gost_cipher_nids[] = 36 {NID_id_Gost28147_89, NID_gost89_cnt,0}; 37 38static int gost_digest_nids[] = 39 {NID_id_GostR3411_94,NID_id_Gost28147_89_MAC, 0}; 40 41static int gost_pkey_meth_nids[] = 42 {NID_id_GostR3410_94, 43 NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0}; 44 45static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL, 46 *pmeth_GostR3410_2001 = NULL, 47 *pmeth_Gost28147_MAC = NULL; 48 49static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL, 50 *ameth_GostR3410_2001 = NULL, 51 *ameth_Gost28147_MAC = NULL; 52 53 54static int gost_engine_init(ENGINE *e) 55 { 56 return 1; 57 } 58 59static int gost_engine_finish(ENGINE *e) 60 { 61 return 1; 62 } 63 64static int gost_engine_destroy(ENGINE *e) 65 { 66 gost_param_free(); 67 return 1; 68 } 69 70static int bind_gost (ENGINE *e,const char *id) 71 { 72 int ret = 0; 73 if (id && strcmp(id, engine_gost_id)) return 0; 74 75 if (!ENGINE_set_id(e, engine_gost_id)) 76 { 77 printf("ENGINE_set_id failed\n"); 78 goto end; 79 } 80 if (!ENGINE_set_name(e, engine_gost_name)) 81 { 82 printf("ENGINE_set_name failed\n"); 83 goto end; 84 } 85 if (!ENGINE_set_digests(e, gost_digests)) 86 { 87 printf("ENGINE_set_digests failed\n"); 88 goto end; 89 } 90 if (! ENGINE_set_ciphers(e, gost_ciphers)) 91 { 92 printf("ENGINE_set_ciphers failed\n"); 93 goto end; 94 } 95 if (! ENGINE_set_pkey_meths(e, gost_pkey_meths)) 96 { 97 printf("ENGINE_set_pkey_meths failed\n"); 98 goto end; 99 } 100 if (! ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) 101 { 102 printf("ENGINE_set_pkey_asn1_meths failed\n"); 103 goto end; 104 } 105 /* Control function and commands */ 106 if (!ENGINE_set_cmd_defns(e,gost_cmds)) 107 { 108 fprintf(stderr,"ENGINE_set_cmd_defns failed\n"); 109 goto end; 110 } 111 if (!ENGINE_set_ctrl_function(e,gost_control_func)) 112 { 113 fprintf(stderr,"ENGINE_set_ctrl_func failed\n"); 114 goto end; 115 } 116 if ( ! ENGINE_set_destroy_function(e, gost_engine_destroy) 117 || ! ENGINE_set_init_function(e,gost_engine_init) 118 || ! ENGINE_set_finish_function(e,gost_engine_finish)) 119 { 120 goto end; 121 } 122 123 if (!register_ameth_gost(NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", "GOST R 34.10-94")) goto end; 124 if (!register_ameth_gost(NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", "GOST R 34.10-2001")) goto end; 125 if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC, 126 "GOST-MAC", "GOST 28147-89 MAC")) goto end; 127 128 if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) goto end; 129 if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) goto end; 130 if (!register_pmeth_gost(NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0)) 131 goto end; 132 if ( ! ENGINE_register_ciphers(e) 133 || ! ENGINE_register_digests(e) 134 || ! ENGINE_register_pkey_meths(e) 135 /* These two actually should go in LIST_ADD command */ 136 || ! EVP_add_cipher(&cipher_gost) 137 || ! EVP_add_cipher(&cipher_gost_cpacnt) 138 || ! EVP_add_digest(&digest_gost) 139 || ! EVP_add_digest(&imit_gost_cpa) 140 ) 141 { 142 goto end; 143 } 144 145 ERR_load_GOST_strings(); 146 ret = 1; 147 end: 148 return ret; 149 } 150 151#ifndef OPENSSL_NO_DYNAMIC_ENGINE 152IMPLEMENT_DYNAMIC_BIND_FN(bind_gost) 153IMPLEMENT_DYNAMIC_CHECK_FN() 154#endif /* ndef OPENSSL_NO_DYNAMIC_ENGINE */ 155 156static int gost_digests(ENGINE *e, const EVP_MD **digest, 157 const int **nids, int nid) 158 { 159 int ok =1 ; 160 if (!digest) 161 { 162 *nids = gost_digest_nids; 163 return 2; 164 } 165 /*printf("Digest no %d requested\n",nid);*/ 166 if(nid == NID_id_GostR3411_94) 167 { 168 *digest = &digest_gost; 169 } 170 else if (nid == NID_id_Gost28147_89_MAC) 171 { 172 *digest = &imit_gost_cpa; 173 } 174 else 175 { 176 ok =0; 177 *digest = NULL; 178 } 179 return ok; 180 } 181 182static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher, 183 const int **nids, int nid) 184 { 185 int ok = 1; 186 if (!cipher) 187 { 188 *nids = gost_cipher_nids; 189 return 2; /* two ciphers are supported */ 190 } 191 192 if(nid == NID_id_Gost28147_89) 193 { 194 *cipher = &cipher_gost; 195 } 196 else if (nid == NID_gost89_cnt) 197 { 198 *cipher = &cipher_gost_cpacnt; 199 } 200 else 201 { 202 ok = 0; 203 *cipher = NULL; 204 } 205 return ok; 206 } 207 208static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, 209 const int **nids, int nid) 210 { 211 if (!pmeth) 212 { 213 *nids = gost_pkey_meth_nids; 214 return 3; 215 } 216 217 switch (nid) 218 { 219 case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1; 220 case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1; 221 case NID_id_Gost28147_89_MAC: *pmeth = pmeth_Gost28147_MAC; return 1; 222 default:; 223 } 224 225 *pmeth = NULL; 226 return 0; 227 } 228 229static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, 230 const int **nids, int nid) 231 { 232 if (!ameth) 233 { 234 *nids = gost_pkey_meth_nids; 235 return 3; 236 } 237 switch (nid) 238 { 239 case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1; 240 case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1; 241 case NID_id_Gost28147_89_MAC: *ameth = ameth_Gost28147_MAC; return 1; 242 243 default:; 244 } 245 246 *ameth = NULL; 247 return 0; 248 } 249 250#ifdef OPENSSL_NO_DYNAMIC_ENGINE 251static ENGINE *engine_gost(void) 252 { 253 ENGINE *ret = ENGINE_new(); 254 if (!ret) 255 return NULL; 256 if (!bind_gost(ret,engine_gost_id)) 257 { 258 ENGINE_free(ret); 259 return NULL; 260 } 261 return ret; 262 } 263 264void ENGINE_load_gost(void) 265 { 266 ENGINE *toadd =engine_gost(); 267 if (!toadd) return; 268 ENGINE_add(toadd); 269 ENGINE_free(toadd); 270 ERR_clear_error(); 271 } 272#endif 273 274