Fix eckey_priv_encode()
[openssl.git] / crypto / ec / ec_ameth.c
1 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2  * project 2006.
3  */
4 /* ====================================================================
5  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer. 
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  *    software must display the following acknowledgment:
21  *    "This product includes software developed by the OpenSSL Project
22  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  *    endorse or promote products derived from this software without
26  *    prior written permission. For written permission, please contact
27  *    licensing@OpenSSL.org.
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  *    nor may "OpenSSL" appear in their names without prior written
31  *    permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  *    acknowledgment:
35  *    "This product includes software developed by the OpenSSL Project
36  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * (eay@cryptsoft.com).  This product includes software written by Tim
54  * Hudson (tjh@cryptsoft.com).
55  *
56  */
57
58 #include <stdio.h>
59 #include "cryptlib.h"
60 #include <openssl/x509.h>
61 #include <openssl/ec.h>
62 #include <openssl/bn.h>
63 #ifndef OPENSSL_NO_CMS
64 #include <openssl/cms.h>
65 #endif
66 #include "asn1_locl.h"
67
68 static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
69         {
70         const EC_GROUP  *group;
71         int nid;
72         if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) 
73         {
74                 ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
75                 return 0;
76         }
77         if (EC_GROUP_get_asn1_flag(group)
78                      && (nid = EC_GROUP_get_curve_name(group)))
79                 /* we have a 'named curve' => just set the OID */
80                 {
81                 *ppval = OBJ_nid2obj(nid);
82                 *pptype = V_ASN1_OBJECT;
83                 }
84         else    /* explicit parameters */
85                 {
86                 ASN1_STRING *pstr = NULL;
87                 pstr = ASN1_STRING_new();
88                 if (!pstr)
89                         return 0;
90                 pstr->length = i2d_ECParameters(ec_key, &pstr->data);
91                 if (pstr->length <= 0)
92                         {
93                         ASN1_STRING_free(pstr);
94                         ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
95                         return 0;
96                         }
97                 *ppval = pstr;
98                 *pptype = V_ASN1_SEQUENCE;
99                 }
100         return 1;
101         }
102
103 static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
104         {
105         EC_KEY *ec_key = pkey->pkey.ec;
106         void *pval = NULL;
107         int ptype;
108         unsigned char *penc = NULL, *p;
109         int penclen;
110
111         if (!eckey_param2type(&ptype, &pval, ec_key))
112                 {
113                 ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
114                 return 0;
115                 }
116         penclen = i2o_ECPublicKey(ec_key, NULL);
117         if (penclen <= 0)
118                 goto err;
119         penc = OPENSSL_malloc(penclen);
120         if (!penc)
121                 goto err;
122         p = penc;
123         penclen = i2o_ECPublicKey(ec_key, &p);
124         if (penclen <= 0)
125                 goto err;
126         if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
127                                 ptype, pval, penc, penclen))
128                 return 1;
129         err:
130         if (ptype == V_ASN1_OBJECT)
131                 ASN1_OBJECT_free(pval);
132         else
133                 ASN1_STRING_free(pval);
134         if (penc)
135                 OPENSSL_free(penc);
136         return 0;
137         }
138
139 static EC_KEY *eckey_type2param(int ptype, void *pval)
140         {
141         EC_KEY *eckey = NULL;
142         if (ptype == V_ASN1_SEQUENCE)
143                 {
144                 ASN1_STRING *pstr = pval;
145                 const unsigned char *pm = NULL;
146                 int pmlen;
147                 pm = pstr->data;
148                 pmlen = pstr->length;
149                 if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen)))
150                         {
151                         ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
152                         goto ecerr;
153                         }
154                 }
155         else if (ptype == V_ASN1_OBJECT)
156                 {
157                 ASN1_OBJECT *poid = pval;
158                 EC_GROUP *group;
159
160                 /* type == V_ASN1_OBJECT => the parameters are given
161                  * by an asn1 OID
162                  */
163                 if ((eckey = EC_KEY_new()) == NULL)
164                         {
165                         ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
166                         goto ecerr;
167                         }
168                 group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
169                 if (group == NULL)
170                         goto ecerr;
171                 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
172                 if (EC_KEY_set_group(eckey, group) == 0)
173                         goto ecerr;
174                 EC_GROUP_free(group);
175                 }
176         else
177                 {
178                 ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
179                 goto ecerr;
180                 }
181
182         return eckey;
183
184         ecerr:
185         if (eckey)
186                 EC_KEY_free(eckey);
187         return NULL;
188         }
189
190 static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
191         {
192         const unsigned char *p = NULL;
193         void *pval;
194         int ptype, pklen;
195         EC_KEY *eckey = NULL;
196         X509_ALGOR *palg;
197
198         if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
199                 return 0;
200         X509_ALGOR_get0(NULL, &ptype, &pval, palg);
201
202         eckey = eckey_type2param(ptype, pval);
203
204         if (!eckey)
205                 {
206                 ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
207                 return 0;
208                 }
209
210         /* We have parameters now set public key */
211         if (!o2i_ECPublicKey(&eckey, &p, pklen))
212                 {
213                 ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
214                 goto ecerr;
215                 }
216
217         EVP_PKEY_assign_EC_KEY(pkey, eckey);
218         return 1;
219
220         ecerr:
221         if (eckey)
222                 EC_KEY_free(eckey);
223         return 0;
224         }
225
226 static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
227         {
228         int  r;
229         const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
230         const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
231                        *pb = EC_KEY_get0_public_key(b->pkey.ec);
232         r = EC_POINT_cmp(group, pa, pb, NULL);
233         if (r == 0)
234                 return 1;
235         if (r == 1)
236                 return 0;
237         return -2;
238         }
239
240 static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
241         {
242         const unsigned char *p = NULL;
243         void *pval;
244         int ptype, pklen;
245         EC_KEY *eckey = NULL;
246         X509_ALGOR *palg;
247
248         if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
249                 return 0;
250         X509_ALGOR_get0(NULL, &ptype, &pval, palg);
251
252         eckey = eckey_type2param(ptype, pval);
253
254         if (!eckey)
255                 goto ecliberr;
256
257         /* We have parameters now set private key */
258         if (!d2i_ECPrivateKey(&eckey, &p, pklen))
259                 {
260                 ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
261                 goto ecerr;
262                 }
263
264         /* calculate public key (if necessary) */
265         if (EC_KEY_get0_public_key(eckey) == NULL)
266                 {
267                 const BIGNUM *priv_key;
268                 const EC_GROUP *group;
269                 EC_POINT *pub_key;
270                 /* the public key was not included in the SEC1 private
271                  * key => calculate the public key */
272                 group   = EC_KEY_get0_group(eckey);
273                 pub_key = EC_POINT_new(group);
274                 if (pub_key == NULL)
275                         {
276                         ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
277                         goto ecliberr;
278                         }
279                 if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
280                         {
281                         EC_POINT_free(pub_key);
282                         ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
283                         goto ecliberr;
284                         }
285                 priv_key = EC_KEY_get0_private_key(eckey);
286                 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL))
287                         {
288                         EC_POINT_free(pub_key);
289                         ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
290                         goto ecliberr;
291                         }
292                 if (EC_KEY_set_public_key(eckey, pub_key) == 0)
293                         {
294                         EC_POINT_free(pub_key);
295                         ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
296                         goto ecliberr;
297                         }
298                 EC_POINT_free(pub_key);
299                 }
300
301         EVP_PKEY_assign_EC_KEY(pkey, eckey);
302         return 1;
303
304         ecliberr:
305         ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
306         ecerr:
307         if (eckey)
308                 EC_KEY_free(eckey);
309         return 0;
310         }
311
312 static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
313 {
314         EC_KEY          *ec_key;
315         unsigned char   *ep, *p;
316         int             eplen, ptype;
317         void            *pval;
318         unsigned int    tmp_flags, old_flags;
319
320         ec_key = pkey->pkey.ec;
321
322         if (!eckey_param2type(&ptype, &pval, ec_key))
323                 {
324                 ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
325                 return 0;
326                 }
327
328         /* set the private key */
329
330         /* do not include the parameters in the SEC1 private key
331          * see PKCS#11 12.11 */
332         old_flags = EC_KEY_get_enc_flags(ec_key);
333         tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
334         EC_KEY_set_enc_flags(ec_key, tmp_flags);
335         eplen = i2d_ECPrivateKey(ec_key, NULL);
336         if (!eplen)
337         {
338                 EC_KEY_set_enc_flags(ec_key, old_flags);
339                 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
340                 return 0;
341         }
342         ep = (unsigned char *) OPENSSL_malloc(eplen);
343         if (!ep)
344         {
345                 EC_KEY_set_enc_flags(ec_key, old_flags);
346                 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
347                 return 0;
348         }
349         p = ep;
350         if (!i2d_ECPrivateKey(ec_key, &p))
351         {
352                 EC_KEY_set_enc_flags(ec_key, old_flags);
353                 OPENSSL_free(ep);
354                 ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
355                 return 0;
356         }
357         /* restore old encoding flags */
358         EC_KEY_set_enc_flags(ec_key, old_flags);
359
360         if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
361                                 ptype, pval, ep, eplen))
362                 return 0;
363
364         return 1;
365 }
366
367 static int int_ec_size(const EVP_PKEY *pkey)
368         {
369         return ECDSA_size(pkey->pkey.ec);
370         }
371
372 static int ec_bits(const EVP_PKEY *pkey)
373         {
374         BIGNUM *order = BN_new();
375         const EC_GROUP *group;
376         int ret;
377
378         if (!order)
379                 {
380                 ERR_clear_error();
381                 return 0;
382                 }
383         group = EC_KEY_get0_group(pkey->pkey.ec);
384         if (!EC_GROUP_get_order(group, order, NULL))
385                 {
386                 ERR_clear_error();
387                 return 0;
388                 }
389
390         ret = BN_num_bits(order);
391         BN_free(order);
392         return ret;
393         }
394
395 static int ec_missing_parameters(const EVP_PKEY *pkey)
396         {
397         if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
398                 return 1;
399         return 0;
400         }
401
402 static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
403         {
404         EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
405         if (group == NULL)
406                 return 0;
407         if (EC_KEY_set_group(to->pkey.ec, group) == 0)
408                 return 0;
409         EC_GROUP_free(group);
410         return 1;
411         }
412
413 static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
414         {
415         const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
416                        *group_b = EC_KEY_get0_group(b->pkey.ec);
417         if (EC_GROUP_cmp(group_a, group_b, NULL))
418                 return 0;
419         else
420                 return 1;
421         }
422
423 static void int_ec_free(EVP_PKEY *pkey)
424         {
425         EC_KEY_free(pkey->pkey.ec);
426         }
427
428 static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
429         {
430         unsigned char *buffer=NULL;
431         const char *ecstr;
432         size_t  buf_len=0, i;
433         int     ret=0, reason=ERR_R_BIO_LIB;
434         BIGNUM  *pub_key=NULL, *order=NULL;
435         BN_CTX  *ctx=NULL;
436         const EC_GROUP *group;
437         const EC_POINT *public_key;
438         const BIGNUM *priv_key;
439  
440         if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
441                 {
442                 reason = ERR_R_PASSED_NULL_PARAMETER;
443                 goto err;
444                 }
445
446         ctx = BN_CTX_new();
447         if (ctx == NULL)
448                 {
449                 reason = ERR_R_MALLOC_FAILURE;
450                 goto err;
451                 }
452
453         if (ktype > 0)
454                 {
455                 public_key = EC_KEY_get0_public_key(x);
456                 if ((pub_key = EC_POINT_point2bn(group, public_key,
457                         EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
458                         {
459                         reason = ERR_R_EC_LIB;
460                         goto err;
461                         }
462                 if (pub_key)
463                         buf_len = (size_t)BN_num_bytes(pub_key);
464                 }
465
466         if (ktype == 2)
467                 {
468                 priv_key = EC_KEY_get0_private_key(x);
469                 if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
470                         buf_len = i;
471                 }
472         else
473                 priv_key = NULL;
474
475         if (ktype > 0)
476                 {
477                 buf_len += 10;
478                 if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
479                         {
480                         reason = ERR_R_MALLOC_FAILURE;
481                         goto err;
482                         }
483                 }
484         if (ktype == 2)
485                 ecstr = "Private-Key";
486         else if (ktype == 1)
487                 ecstr = "Public-Key";
488         else
489                 ecstr = "ECDSA-Parameters";
490
491         if (!BIO_indent(bp, off, 128))
492                 goto err;
493         if ((order = BN_new()) == NULL)
494                 goto err;
495         if (!EC_GROUP_get_order(group, order, NULL))
496                 goto err;
497         if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
498                 BN_num_bits(order)) <= 0) goto err;
499   
500         if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, 
501                 buffer, off))
502                 goto err;
503         if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
504                 buffer, off))
505                 goto err;
506         if (!ECPKParameters_print(bp, group, off))
507                 goto err;
508         ret=1;
509 err:
510         if (!ret)
511                 ECerr(EC_F_DO_EC_KEY_PRINT, reason);
512         if (pub_key) 
513                 BN_free(pub_key);
514         if (order)
515                 BN_free(order);
516         if (ctx)
517                 BN_CTX_free(ctx);
518         if (buffer != NULL)
519                 OPENSSL_free(buffer);
520         return(ret);
521         }
522
523 static int eckey_param_decode(EVP_PKEY *pkey,
524                                         const unsigned char **pder, int derlen)
525         {
526         EC_KEY *eckey;
527         if (!(eckey = d2i_ECParameters(NULL, pder, derlen)))
528                 {
529                 ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
530                 return 0;
531                 }
532         EVP_PKEY_assign_EC_KEY(pkey, eckey);
533         return 1;
534         }
535
536 static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
537         {
538         return i2d_ECParameters(pkey->pkey.ec, pder);
539         }
540
541 static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
542                                                         ASN1_PCTX *ctx)
543         {
544         return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
545         }
546
547 static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
548                                                         ASN1_PCTX *ctx)
549         {
550         return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
551         }
552
553
554 static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
555                                                         ASN1_PCTX *ctx)
556         {
557         return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
558         }
559
560 static int old_ec_priv_decode(EVP_PKEY *pkey,
561                                         const unsigned char **pder, int derlen)
562         {
563         EC_KEY *ec;
564         if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen)))
565                 {
566                 ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
567                 return 0;
568                 }
569         EVP_PKEY_assign_EC_KEY(pkey, ec);
570         return 1;
571         }
572
573 static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
574         {
575         return i2d_ECPrivateKey(pkey->pkey.ec, pder);
576         }
577
578 static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
579         {
580         switch (op)
581                 {
582                 case ASN1_PKEY_CTRL_PKCS7_SIGN:
583                 if (arg1 == 0)
584                         {
585                         int snid, hnid;
586                         X509_ALGOR *alg1, *alg2;
587                         PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
588                         if (alg1 == NULL || alg1->algorithm == NULL)
589                                 return -1;
590                         hnid = OBJ_obj2nid(alg1->algorithm);
591                         if (hnid == NID_undef)
592                                 return -1;
593                         if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
594                                 return -1; 
595                         X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
596                         }
597                 return 1;
598 #ifndef OPENSSL_NO_CMS
599                 case ASN1_PKEY_CTRL_CMS_SIGN:
600                 if (arg1 == 0)
601                         {
602                         int snid, hnid;
603                         X509_ALGOR *alg1, *alg2;
604                         CMS_SignerInfo_get0_algs(arg2, NULL, NULL,
605                                                                 &alg1, &alg2);
606                         if (alg1 == NULL || alg1->algorithm == NULL)
607                                 return -1;
608                         hnid = OBJ_obj2nid(alg1->algorithm);
609                         if (hnid == NID_undef)
610                                 return -1;
611                         if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
612                                 return -1; 
613                         X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
614                         }
615                 return 1;
616 #endif
617
618                 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
619                 *(int *)arg2 = NID_sha1;
620                 return 2;
621
622                 default:
623                 return -2;
624
625                 }
626
627         }
628
629 const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = 
630         {
631         EVP_PKEY_EC,
632         EVP_PKEY_EC,
633         0,
634         "EC",
635         "OpenSSL EC algorithm",
636
637         eckey_pub_decode,
638         eckey_pub_encode,
639         eckey_pub_cmp,
640         eckey_pub_print,
641
642         eckey_priv_decode,
643         eckey_priv_encode,
644         eckey_priv_print,
645
646         int_ec_size,
647         ec_bits,
648
649         eckey_param_decode,
650         eckey_param_encode,
651         ec_missing_parameters,
652         ec_copy_parameters,
653         ec_cmp_parameters,
654         eckey_param_print,
655         0,
656
657         int_ec_free,
658         ec_pkey_ctrl,
659         old_ec_priv_decode,
660         old_ec_priv_encode
661         };