OLD | NEW |
(Empty) | |
| 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" |
| 18 static const char *engine_gost_id = "gost"; |
| 19 static const char *engine_gost_name = "Reference implementation of GOST engine"; |
| 20 |
| 21 /* Symmetric cipher and digest function registrar */ |
| 22 |
| 23 static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher, |
| 24 const int **nids, int nid); |
| 25 |
| 26 static int gost_digests(ENGINE *e, const EVP_MD **digest, |
| 27 const int **nids, int ind); |
| 28 |
| 29 static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, |
| 30 const int **nids, int nid); |
| 31 |
| 32 static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, |
| 33 const int **nids, int nid); |
| 34 |
| 35 static int gost_cipher_nids[] = |
| 36 {NID_id_Gost28147_89, NID_gost89_cnt,0}; |
| 37 |
| 38 static int gost_digest_nids[] = |
| 39 {NID_id_GostR3411_94,NID_id_Gost28147_89_MAC, 0}; |
| 40 |
| 41 static int gost_pkey_meth_nids[] = |
| 42 {NID_id_GostR3410_94, |
| 43 NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0}; |
| 44 |
| 45 static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL, |
| 46 *pmeth_GostR3410_2001 = NULL, |
| 47 *pmeth_Gost28147_MAC = NULL; |
| 48 |
| 49 static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL, |
| 50 *ameth_GostR3410_2001 = NULL, |
| 51 *ameth_Gost28147_MAC = NULL; |
| 52 |
| 53 |
| 54 static int gost_engine_init(ENGINE *e) |
| 55 { |
| 56 return 1; |
| 57 } |
| 58 |
| 59 static int gost_engine_finish(ENGINE *e) |
| 60 { |
| 61 return 1; |
| 62 } |
| 63 |
| 64 static int gost_engine_destroy(ENGINE *e) |
| 65 { |
| 66 gost_param_free(); |
| 67 return 1; |
| 68 } |
| 69 |
| 70 static 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, "GOST
94", "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)) g
oto 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 |
| 152 IMPLEMENT_DYNAMIC_BIND_FN(bind_gost) |
| 153 IMPLEMENT_DYNAMIC_CHECK_FN() |
| 154 #endif /* ndef OPENSSL_NO_DYNAMIC_ENGINE */ |
| 155 |
| 156 static 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 |
| 182 static 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 |
| 208 static 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; retur
n 1; |
| 221 case NID_id_Gost28147_89_MAC: *pmeth = pmeth_Gost28147_MAC; retu
rn 1; |
| 222 default:; |
| 223 } |
| 224 |
| 225 *pmeth = NULL; |
| 226 return 0; |
| 227 } |
| 228 |
| 229 static 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; retur
n 1; |
| 241 case NID_id_Gost28147_89_MAC: *ameth = ameth_Gost28147_MAC; retu
rn 1; |
| 242 |
| 243 default:; |
| 244 } |
| 245 |
| 246 *ameth = NULL; |
| 247 return 0; |
| 248 } |
| 249 |
| 250 #ifdef OPENSSL_NO_DYNAMIC_ENGINE |
| 251 static 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 |
| 264 void 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 |
OLD | NEW |