OLD | NEW |
(Empty) | |
| 1 /********************************************************************** |
| 2 * gost_pmeth.c * |
| 3 * Copyright (c) 2005-2006 Cryptocom LTD * |
| 4 * This file is distributed under the same license as OpenSSL * |
| 5 * * |
| 6 * Implementation of RFC 4357 (GOST R 34.10) Publick key method * |
| 7 * for OpenSSL * |
| 8 * Requires OpenSSL 0.9.9 for compilation * |
| 9 **********************************************************************/ |
| 10 #include <openssl/evp.h> |
| 11 #include <openssl/objects.h> |
| 12 #include <openssl/ec.h> |
| 13 #include <openssl/x509v3.h> /*For string_to_hex */ |
| 14 #include <stdlib.h> |
| 15 #include <string.h> |
| 16 #include <ctype.h> |
| 17 #include "gost_params.h" |
| 18 #include "gost_lcl.h" |
| 19 #include "e_gost_err.h" |
| 20 /*-------init, cleanup, copy - uniform for all algs ---------------*/ |
| 21 /* Allocates new gost_pmeth_data structure and assigns it as data */ |
| 22 static int pkey_gost_init(EVP_PKEY_CTX *ctx) |
| 23 { |
| 24 struct gost_pmeth_data *data; |
| 25 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); |
| 26 data = OPENSSL_malloc(sizeof(struct gost_pmeth_data)); |
| 27 if (!data) return 0; |
| 28 memset(data,0,sizeof(struct gost_pmeth_data)); |
| 29 if (pkey && EVP_PKEY_get0(pkey)) |
| 30 { |
| 31 switch (EVP_PKEY_base_id(pkey)) { |
| 32 case NID_id_GostR3410_94: |
| 33 data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey
)); |
| 34 break; |
| 35 case NID_id_GostR3410_2001: |
| 36 data->sign_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_gr
oup(EVP_PKEY_get0((EVP_PKEY *)pkey))); |
| 37 break; |
| 38 default: |
| 39 return 0; |
| 40 } |
| 41 } |
| 42 EVP_PKEY_CTX_set_data(ctx,data); |
| 43 return 1; |
| 44 } |
| 45 |
| 46 /* Copies contents of gost_pmeth_data structure */ |
| 47 static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) |
| 48 { |
| 49 struct gost_pmeth_data *dst_data,*src_data; |
| 50 if (!pkey_gost_init(dst)) |
| 51 { |
| 52 return 0; |
| 53 } |
| 54 src_data = EVP_PKEY_CTX_get_data(src); |
| 55 dst_data = EVP_PKEY_CTX_get_data(dst); |
| 56 *dst_data = *src_data; |
| 57 if (src_data -> shared_ukm) { |
| 58 dst_data->shared_ukm=NULL; |
| 59 } |
| 60 return 1; |
| 61 } |
| 62 |
| 63 /* Frees up gost_pmeth_data structure */ |
| 64 static void pkey_gost_cleanup (EVP_PKEY_CTX *ctx) |
| 65 { |
| 66 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); |
| 67 if (data->shared_ukm) OPENSSL_free(data->shared_ukm); |
| 68 OPENSSL_free(data); |
| 69 } |
| 70 |
| 71 /* --------------------- control functions ------------------------------*/ |
| 72 static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) |
| 73 { |
| 74 struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get
_data(ctx); |
| 75 switch (type) |
| 76 { |
| 77 case EVP_PKEY_CTRL_MD: |
| 78 { |
| 79 if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94) |
| 80 { |
| 81 GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYP
E); |
| 82 return 0; |
| 83 } |
| 84 pctx->md = (EVP_MD *)p2; |
| 85 return 1; |
| 86 } |
| 87 break; |
| 88 |
| 89 case EVP_PKEY_CTRL_PKCS7_ENCRYPT: |
| 90 case EVP_PKEY_CTRL_PKCS7_DECRYPT: |
| 91 case EVP_PKEY_CTRL_PKCS7_SIGN: |
| 92 return 1; |
| 93 |
| 94 case EVP_PKEY_CTRL_GOST_PARAMSET: |
| 95 pctx->sign_param_nid = (int)p1; |
| 96 return 1; |
| 97 case EVP_PKEY_CTRL_SET_IV: |
| 98 pctx->shared_ukm=OPENSSL_malloc((int)p1); |
| 99 memcpy(pctx->shared_ukm,p2,(int) p1); |
| 100 return 1; |
| 101 case EVP_PKEY_CTRL_PEER_KEY: |
| 102 if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set
_peer */ |
| 103 return 1; |
| 104 if (p1 == 2) /* TLS: peer key used? */ |
| 105 return pctx->peer_key_used; |
| 106 if (p1 == 3) /* TLS: peer key used! */ |
| 107 return (pctx->peer_key_used = 1); |
| 108 return -2; |
| 109 } |
| 110 return -2; |
| 111 } |
| 112 |
| 113 |
| 114 static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx, |
| 115 const char *type, const char *value) |
| 116 { |
| 117 int param_nid=0; |
| 118 if(!strcmp(type, param_ctrl_string)) |
| 119 { |
| 120 if (!value) |
| 121 { |
| 122 return 0; |
| 123 } |
| 124 if (strlen(value) == 1) |
| 125 { |
| 126 switch(toupper(value[0])) |
| 127 { |
| 128 case 'A': |
| 129 param_nid = NID_id_GostR3410_94_CryptoPr
o_A_ParamSet; |
| 130 break; |
| 131 case 'B': |
| 132 param_nid = NID_id_GostR3410_94_CryptoPr
o_B_ParamSet; |
| 133 break; |
| 134 case 'C': |
| 135 param_nid = NID_id_GostR3410_94_CryptoPr
o_C_ParamSet; |
| 136 break; |
| 137 case 'D': |
| 138 param_nid = NID_id_GostR3410_94_CryptoPr
o_D_ParamSet; |
| 139 break; |
| 140 default: |
| 141 return 0; |
| 142 break; |
| 143 } |
| 144 } |
| 145 else if ((strlen(value) == 2) && (toupper(value[0]) == 'X')) |
| 146 { |
| 147 switch (toupper(value[1])) |
| 148 { |
| 149 case 'A': |
| 150 param_nid = NID_id_GostR3410_94_CryptoPr
o_XchA_ParamSet; |
| 151 break; |
| 152 case 'B': |
| 153 param_nid = NID_id_GostR3410_94_CryptoPr
o_XchB_ParamSet; |
| 154 break; |
| 155 case 'C': |
| 156 param_nid = NID_id_GostR3410_94_CryptoPr
o_XchC_ParamSet; |
| 157 break; |
| 158 default: |
| 159 return 0; |
| 160 break; |
| 161 } |
| 162 } |
| 163 else |
| 164 { |
| 165 R3410_params *p = R3410_paramset; |
| 166 param_nid = OBJ_txt2nid(value); |
| 167 if (param_nid == NID_undef) |
| 168 { |
| 169 return 0; |
| 170 } |
| 171 for (;p->nid != NID_undef;p++) |
| 172 { |
| 173 if (p->nid == param_nid) break; |
| 174 } |
| 175 if (p->nid == NID_undef) |
| 176 { |
| 177 GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR, |
| 178 GOST_R_INVALID_PARAMSET); |
| 179 return 0; |
| 180 } |
| 181 } |
| 182 |
| 183 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, |
| 184 param_nid, NULL); |
| 185 } |
| 186 return -2; |
| 187 } |
| 188 |
| 189 static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx, |
| 190 const char *type, const char *value) |
| 191 { |
| 192 int param_nid=0; |
| 193 if(!strcmp(type, param_ctrl_string)) |
| 194 { |
| 195 if (!value) |
| 196 { |
| 197 return 0; |
| 198 } |
| 199 if (strlen(value) == 1) |
| 200 { |
| 201 switch(toupper(value[0])) |
| 202 { |
| 203 case 'A': |
| 204 param_nid = NID_id_GostR3410_2001_Crypto
Pro_A_ParamSet; |
| 205 break; |
| 206 case 'B': |
| 207 param_nid = NID_id_GostR3410_2001_Crypto
Pro_B_ParamSet; |
| 208 break; |
| 209 case 'C': |
| 210 param_nid = NID_id_GostR3410_2001_Crypto
Pro_C_ParamSet; |
| 211 break; |
| 212 case '0': |
| 213 param_nid = NID_id_GostR3410_2001_TestPa
ramSet; |
| 214 break; |
| 215 default: |
| 216 return 0; |
| 217 break; |
| 218 } |
| 219 } |
| 220 else if ((strlen(value) == 2) && (toupper(value[0]) == 'X')) |
| 221 { |
| 222 switch (toupper(value[1])) |
| 223 { |
| 224 case 'A': |
| 225 param_nid = NID_id_GostR3410_2001_Crypto
Pro_XchA_ParamSet; |
| 226 break; |
| 227 case 'B': |
| 228 param_nid = NID_id_GostR3410_2001_Crypto
Pro_XchB_ParamSet; |
| 229 break; |
| 230 default: |
| 231 return 0; |
| 232 break; |
| 233 } |
| 234 } |
| 235 else |
| 236 { |
| 237 R3410_2001_params *p = R3410_2001_paramset; |
| 238 param_nid = OBJ_txt2nid(value); |
| 239 if (param_nid == NID_undef) |
| 240 { |
| 241 return 0; |
| 242 } |
| 243 for (;p->nid != NID_undef;p++) |
| 244 { |
| 245 if (p->nid == param_nid) break; |
| 246 } |
| 247 if (p->nid == NID_undef) |
| 248 { |
| 249 GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR, |
| 250 GOST_R_INVALID_PARAMSET); |
| 251 return 0; |
| 252 } |
| 253 } |
| 254 |
| 255 return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, |
| 256 param_nid, NULL); |
| 257 } |
| 258 return -2; |
| 259 } |
| 260 |
| 261 /* --------------------- key generation --------------------------------*/ |
| 262 |
| 263 static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx) { |
| 264 return 1; |
| 265 } |
| 266 static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) |
| 267 { |
| 268 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); |
| 269 DSA *dsa=NULL; |
| 270 if (data->sign_param_nid == NID_undef) |
| 271 { |
| 272 GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN, |
| 273 GOST_R_NO_PARAMETERS_SET); |
| 274 return 0; |
| 275 } |
| 276 dsa = DSA_new(); |
| 277 if (!fill_GOST94_params(dsa,data->sign_param_nid)) |
| 278 { |
| 279 DSA_free(dsa); |
| 280 return 0; |
| 281 } |
| 282 EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa); |
| 283 return 1; |
| 284 } |
| 285 static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) |
| 286 { |
| 287 struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); |
| 288 EC_KEY *ec=NULL; |
| 289 |
| 290 if (data->sign_param_nid == NID_undef) |
| 291 { |
| 292 GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, |
| 293 GOST_R_NO_PARAMETERS_SET); |
| 294 return 0; |
| 295 } |
| 296 if (!ec) |
| 297 ec = EC_KEY_new(); |
| 298 if (!fill_GOST2001_params(ec,data->sign_param_nid)) |
| 299 { |
| 300 EC_KEY_free(ec); |
| 301 return 0; |
| 302 } |
| 303 EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec); |
| 304 return 1; |
| 305 } |
| 306 |
| 307 /* Generates Gost_R3410_94_cp key */ |
| 308 static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) |
| 309 { |
| 310 DSA *dsa; |
| 311 if (!pkey_gost94_paramgen(ctx,pkey)) return 0; |
| 312 dsa = EVP_PKEY_get0(pkey); |
| 313 gost_sign_keygen(dsa); |
| 314 return 1; |
| 315 } |
| 316 |
| 317 /* Generates GOST_R3410 2001 key and assigns it using specified type */ |
| 318 static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) |
| 319 { |
| 320 EC_KEY *ec; |
| 321 if (!pkey_gost01_paramgen(ctx,pkey)) return 0; |
| 322 ec = EVP_PKEY_get0(pkey); |
| 323 gost2001_keygen(ec); |
| 324 return 1; |
| 325 } |
| 326 |
| 327 |
| 328 |
| 329 /* ----------- sign callbacks --------------------------------------*/ |
| 330 |
| 331 static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *si
glen, |
| 332 const unsigned char *tbs, size_t tbs_len) |
| 333 { |
| 334 DSA_SIG *unpacked_sig=NULL; |
| 335 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); |
| 336 if (!siglen) return 0; |
| 337 if (!sig) |
| 338 { |
| 339 *siglen= 64; /* better to check size of pkey->pkey.dsa-q */ |
| 340 return 1; |
| 341 } |
| 342 unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey)); |
| 343 if (!unpacked_sig) |
| 344 { |
| 345 return 0; |
| 346 } |
| 347 return pack_sign_cp(unpacked_sig,32,sig,siglen); |
| 348 } |
| 349 |
| 350 static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *si
glen, |
| 351 const unsigned char *tbs, size_t tbs_len) |
| 352 { |
| 353 DSA_SIG *unpacked_sig=NULL; |
| 354 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); |
| 355 if (!siglen) return 0; |
| 356 if (!sig) |
| 357 { |
| 358 *siglen= 64; /* better to check size of curve order*/ |
| 359 return 1; |
| 360 } |
| 361 unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey)); |
| 362 if (!unpacked_sig) |
| 363 { |
| 364 return 0; |
| 365 } |
| 366 return pack_sign_cp(unpacked_sig,32,sig,siglen); |
| 367 } |
| 368 |
| 369 /* ------------------- verify callbacks ---------------------------*/ |
| 370 |
| 371 static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, |
| 372 size_t siglen, const unsigned char *tbs, size_t tbs_len) |
| 373 { |
| 374 int ok = 0; |
| 375 EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx); |
| 376 DSA_SIG *s=unpack_cp_signature(sig,siglen); |
| 377 if (!s) return 0; |
| 378 if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key)); |
| 379 DSA_SIG_free(s); |
| 380 return ok; |
| 381 } |
| 382 |
| 383 |
| 384 static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, |
| 385 size_t siglen, const unsigned char *tbs, size_t tbs_len) |
| 386 { |
| 387 int ok = 0; |
| 388 EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx); |
| 389 DSA_SIG *s=unpack_cp_signature(sig,siglen); |
| 390 if (!s) return 0; |
| 391 #ifdef DEBUG_SIGN |
| 392 fprintf(stderr,"R="); |
| 393 BN_print_fp(stderr,s->r); |
| 394 fprintf(stderr,"\nS="); |
| 395 BN_print_fp(stderr,s->s); |
| 396 fprintf(stderr,"\n"); |
| 397 #endif |
| 398 if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key
)); |
| 399 DSA_SIG_free(s); |
| 400 return ok; |
| 401 } |
| 402 |
| 403 /* ------------- encrypt init -------------------------------------*/ |
| 404 /* Generates ephermeral key */ |
| 405 static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx) |
| 406 { |
| 407 return 1; |
| 408 } |
| 409 /* --------------- Derive init ------------------------------------*/ |
| 410 static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx) |
| 411 { |
| 412 return 1; |
| 413 } |
| 414 /* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/ |
| 415 static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx) |
| 416 { |
| 417 struct gost_mac_pmeth_data *data; |
| 418 data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data)); |
| 419 if (!data) return 0; |
| 420 memset(data,0,sizeof(struct gost_mac_pmeth_data)); |
| 421 EVP_PKEY_CTX_set_data(ctx,data); |
| 422 return 1; |
| 423 } |
| 424 static void pkey_gost_mac_cleanup (EVP_PKEY_CTX *ctx) |
| 425 { |
| 426 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); |
| 427 OPENSSL_free(data); |
| 428 } |
| 429 static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) |
| 430 { |
| 431 struct gost_mac_pmeth_data *dst_data,*src_data; |
| 432 if (!pkey_gost_mac_init(dst)) |
| 433 { |
| 434 return 0; |
| 435 } |
| 436 src_data = EVP_PKEY_CTX_get_data(src); |
| 437 dst_data = EVP_PKEY_CTX_get_data(dst); |
| 438 *dst_data = *src_data; |
| 439 return 1; |
| 440 } |
| 441 |
| 442 static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) |
| 443 { |
| 444 struct gost_mac_pmeth_data *data = |
| 445 (struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx); |
| 446 |
| 447 switch (type) |
| 448 { |
| 449 case EVP_PKEY_CTRL_MD: |
| 450 { |
| 451 if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC) |
| 452 { |
| 453 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST
_TYPE); |
| 454 return 0; |
| 455 } |
| 456 data->md = (EVP_MD *)p2; |
| 457 return 1; |
| 458 } |
| 459 break; |
| 460 |
| 461 case EVP_PKEY_CTRL_PKCS7_ENCRYPT: |
| 462 case EVP_PKEY_CTRL_PKCS7_DECRYPT: |
| 463 case EVP_PKEY_CTRL_PKCS7_SIGN: |
| 464 return 1; |
| 465 case EVP_PKEY_CTRL_SET_MAC_KEY: |
| 466 if (p1 != 32) |
| 467 { |
| 468 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, |
| 469 GOST_R_INVALID_MAC_KEY_LENGTH); |
| 470 return 0; |
| 471 } |
| 472 |
| 473 memcpy(data->key,p2,32); |
| 474 data->key_set = 1; |
| 475 return 1; |
| 476 case EVP_PKEY_CTRL_DIGESTINIT: |
| 477 { |
| 478 EVP_MD_CTX *mctx = p2; |
| 479 void *key; |
| 480 if (!data->key_set) |
| 481 { |
| 482 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); |
| 483 if (!pkey) |
| 484 { |
| 485 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R
_MAC_KEY_NOT_SET); |
| 486 return 0; |
| 487 } |
| 488 key = EVP_PKEY_get0(pkey); |
| 489 if (!key) |
| 490 { |
| 491 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R
_MAC_KEY_NOT_SET); |
| 492 return 0; |
| 493 } |
| 494 } else { |
| 495 key = &(data->key); |
| 496 } |
| 497 return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32
,key); |
| 498 } |
| 499 } |
| 500 return -2; |
| 501 } |
| 502 static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, |
| 503 const char *type, const char *value) |
| 504 { |
| 505 if (!strcmp(type, key_ctrl_string)) |
| 506 { |
| 507 if (strlen(value)!=32) |
| 508 { |
| 509 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, |
| 510 GOST_R_INVALID_MAC_KEY_LENGTH); |
| 511 return 0; |
| 512 } |
| 513 return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, |
| 514 32,(char *)value); |
| 515 } |
| 516 if (!strcmp(type, hexkey_ctrl_string)) |
| 517 { |
| 518 long keylen; int ret; |
| 519 unsigned char *keybuf=string_to_hex(value,&keylen); |
| 520 if (keylen != 32) |
| 521 { |
| 522 GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, |
| 523 GOST_R_INVALID_MAC_KEY_LENGTH); |
| 524 return 0; |
| 525 } |
| 526 ret= pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, |
| 527 32,keybuf); |
| 528 OPENSSL_free(keybuf); |
| 529 return ret; |
| 530 |
| 531 } |
| 532 return -2; |
| 533 } |
| 534 |
| 535 static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) |
| 536 { |
| 537 struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); |
| 538 unsigned char *keydata; |
| 539 if (!data->key_set) |
| 540 { |
| 541 GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN,GOST_R_MAC_KEY_NOT_S
ET); |
| 542 return 0; |
| 543 } |
| 544 keydata = OPENSSL_malloc(32); |
| 545 memcpy(keydata,data->key,32); |
| 546 EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); |
| 547 return 1; |
| 548 } |
| 549 |
| 550 static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) |
| 551 { |
| 552 return 1; |
| 553 } |
| 554 |
| 555 static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *
siglen, EVP_MD_CTX *mctx) |
| 556 { |
| 557 unsigned int tmpsiglen=*siglen; /* for platforms where sizeof(in
t)!=sizeof(size_t)*/ |
| 558 int ret; |
| 559 if (!sig) |
| 560 { |
| 561 *siglen = 4; |
| 562 return 1; |
| 563 } |
| 564 ret=EVP_DigestFinal_ex(mctx,sig,&tmpsiglen); |
| 565 *siglen = tmpsiglen; |
| 566 return ret; |
| 567 } |
| 568 /* ----------------------------------------------------------------*/ |
| 569 int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) |
| 570 { |
| 571 *pmeth = EVP_PKEY_meth_new(id, flags); |
| 572 if (!*pmeth) return 0; |
| 573 |
| 574 switch (id) |
| 575 { |
| 576 case NID_id_GostR3410_94: |
| 577 EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_
ctrl94_str); |
| 578 EVP_PKEY_meth_set_keygen(*pmeth,NULL,pkey_gost94cp_keyge
n); |
| 579 EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign
); |
| 580 EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_ve
rify); |
| 581 EVP_PKEY_meth_set_encrypt(*pmeth, |
| 582 pkey_gost_encrypt_init, pkey_GOST94cp_encrypt); |
| 583 EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_de
crypt); |
| 584 EVP_PKEY_meth_set_derive(*pmeth, |
| 585 pkey_gost_derive_init, pkey_gost94_derive); |
| 586 EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_in
it,pkey_gost94_paramgen); |
| 587 break; |
| 588 case NID_id_GostR3410_2001: |
| 589 EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_
ctrl01_str); |
| 590 EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign
); |
| 591 EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_ve
rify); |
| 592 |
| 593 EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_key
gen); |
| 594 |
| 595 EVP_PKEY_meth_set_encrypt(*pmeth, |
| 596 pkey_gost_encrypt_init, pkey_GOST01cp_encrypt); |
| 597 EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_de
crypt); |
| 598 EVP_PKEY_meth_set_derive(*pmeth, |
| 599 pkey_gost_derive_init, pkey_gost2001_derive); |
| 600 EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_in
it,pkey_gost01_paramgen); |
| 601 break; |
| 602 case NID_id_Gost28147_89_MAC: |
| 603 EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_mac_ctrl, pkey_g
ost_mac_ctrl_str); |
| 604 EVP_PKEY_meth_set_signctx(*pmeth,pkey_gost_mac_signctx_i
nit, pkey_gost_mac_signctx); |
| 605 EVP_PKEY_meth_set_keygen(*pmeth,NULL, pkey_gost_mac_keyg
en); |
| 606 EVP_PKEY_meth_set_init(*pmeth,pkey_gost_mac_init); |
| 607 EVP_PKEY_meth_set_cleanup(*pmeth,pkey_gost_mac_cleanup); |
| 608 EVP_PKEY_meth_set_copy(*pmeth,pkey_gost_mac_copy); |
| 609 return 1; |
| 610 default: /*Unsupported method*/ |
| 611 return 0; |
| 612 } |
| 613 EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init); |
| 614 EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup); |
| 615 |
| 616 EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy); |
| 617 /*FIXME derive etc...*/ |
| 618 |
| 619 return 1; |
| 620 } |
| 621 |
OLD | NEW |