1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/ec/ec_asn1.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Written by Nils Larsch for the OpenSSL project.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 2000-2003 The OpenSSL Project.  All rights reserved.
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    licensing@OpenSSL.org.
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h>
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "ec_lcl.h"
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h>
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/asn1t.h>
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/objects.h>
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint EC_GROUP_get_basis_type(const EC_GROUP *group)
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i=0;
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		NID_X9_62_characteristic_two_field)
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* everything else is currently not supported */
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while (group->poly[i] != 0)
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i++;
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (i == 4)
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NID_X9_62_ppBasis;
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (i == 2)
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NID_X9_62_tpBasis;
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* everything else is currently not supported */
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
86392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_EC2M
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group == NULL)
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0)))
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (k)
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*k = group->poly[1];
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int *k2, unsigned int *k3)
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group == NULL)
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0)))
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (k1)
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*k1 = group->poly[3];
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (k2)
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*k2 = group->poly[2];
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (k3)
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*k3 = group->poly[1];
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
126392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* some structures needed for the asn1 encoding */
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct x9_62_pentanomial_st {
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long k1;
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long k2;
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long k3;
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} X9_62_PENTANOMIAL;
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct x9_62_characteristic_two_st {
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long m;
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_OBJECT  *type;
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	union	{
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		char *ptr;
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* NID_X9_62_onBasis */
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1_NULL    *onBasis;
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* NID_X9_62_tpBasis */
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1_INTEGER *tpBasis;
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* NID_X9_62_ppBasis */
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X9_62_PENTANOMIAL *ppBasis;
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* anything else */
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1_TYPE *other;
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} p;
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} X9_62_CHARACTERISTIC_TWO;
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct x9_62_fieldid_st {
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        ASN1_OBJECT *fieldType;
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	union	{
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		char *ptr;
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* NID_X9_62_prime_field */
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1_INTEGER *prime;
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* NID_X9_62_characteristic_two_field */
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X9_62_CHARACTERISTIC_TWO *char_two;
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* anything else */
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1_TYPE *other;
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} p;
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} X9_62_FIELDID;
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct x9_62_curve_st {
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        ASN1_OCTET_STRING *a;
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        ASN1_OCTET_STRING *b;
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        ASN1_BIT_STRING   *seed;
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        } X9_62_CURVE;
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct ec_parameters_st {
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        long              version;
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        X9_62_FIELDID     *fieldID;
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        X9_62_CURVE       *curve;
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        ASN1_OCTET_STRING *base;
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        ASN1_INTEGER      *order;
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        ASN1_INTEGER      *cofactor;
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        } ECPARAMETERS;
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct ecpk_parameters_st {
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	type;
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	union {
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1_OBJECT  *named_curve;
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECPARAMETERS *parameters;
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1_NULL    *implicitlyCA;
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} value;
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}/* ECPKPARAMETERS */;
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* SEC1 ECPrivateKey */
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct ec_privatekey_st {
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long              version;
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_OCTET_STRING *privateKey;
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        ECPKPARAMETERS    *parameters;
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_BIT_STRING   *publicKey;
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} EC_PRIVATEKEY;
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* the OpenSSL ASN.1 definitions */
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectDECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectDECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_ADB(X9_62_FIELDID) = {
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_SEQUENCE(X9_62_FIELDID) = {
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_ADB_OBJECT(X9_62_FIELDID)
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_SEQUENCE_END(X9_62_FIELDID)
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_SEQUENCE(X9_62_CURVE) = {
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_SEQUENCE_END(X9_62_CURVE)
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_SEQUENCE(ECPARAMETERS) = {
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(ECPARAMETERS, version, LONG),
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_SEQUENCE_END(ECPARAMETERS)
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectDECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_CHOICE(ECPKPARAMETERS) = {
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_CHOICE_END(ECPKPARAMETERS)
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectDECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectDECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectASN1_SEQUENCE(EC_PRIVATEKEY) = {
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ASN1_SEQUENCE_END(EC_PRIVATEKEY)
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectDECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectDECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectIMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* some declarations of internal function */
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ec_asn1_parameters2group() creates a EC_GROUP object from a
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ECPARAMETERS object */
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EC_GROUP object */
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,ECPARAMETERS *);
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ECPKPARAMETERS object */
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *);
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EC_GROUP object */
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *,
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ECPKPARAMETERS *);
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* the function definitions */
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int			ok=0, nid;
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIGNUM			*tmp = NULL;
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group == NULL || field == NULL)
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* clear the old values (if necessary) */
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (field->fieldType != NULL)
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1_OBJECT_free(field->fieldType);
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (field->p.other != NULL)
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1_TYPE_free(field->p.other);
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* set OID for the field */
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((field->fieldType = OBJ_nid2obj(nid)) == NULL)
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (nid == NID_X9_62_prime_field)
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((tmp = BN_new()) == NULL)
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* the parameters are specified by the prime number p */
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL))
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* set the prime number */
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		field->p.prime = BN_to_ASN1_INTEGER(tmp,NULL);
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (field->p.prime == NULL)
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else	/* nid == NID_X9_62_characteristic_two_field */
342392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_NO_EC2M
343392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
344392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
345392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		goto err;
346392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
347392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		int		field_type;
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X9_62_CHARACTERISTIC_TWO *char_two;
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		char_two = field->p.char_two;
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (char_two == NULL)
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		char_two->m = (long)EC_GROUP_get_degree(group);
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		field_type = EC_GROUP_get_basis_type(group);
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (field_type == 0)
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* set base type OID */
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((char_two->type = OBJ_nid2obj(field_type)) == NULL)
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (field_type == NID_X9_62_tpBasis)
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned int k;
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!EC_GROUP_get_trinomial_basis(group, &k))
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			char_two->p.tpBasis = ASN1_INTEGER_new();
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!char_two->p.tpBasis)
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k))
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ECerr(EC_F_EC_ASN1_GROUP2FIELDID,
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ERR_R_ASN1_LIB);
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (field_type == NID_X9_62_ppBasis)
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned int k1, k2, k3;
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!char_two->p.ppBasis)
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* set k? values */
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			char_two->p.ppBasis->k1 = (long)k1;
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			char_two->p.ppBasis->k2 = (long)k2;
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			char_two->p.ppBasis->k3 = (long)k3;
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else /* field_type == NID_X9_62_onBasis */
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* for ONB the parameters are (asn1) NULL */
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			char_two->p.onBasis = ASN1_NULL_new();
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!char_two->p.onBasis)
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
427392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok = 1;
430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr :	if (tmp)
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(tmp);
433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ok);
434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int           ok=0, nid;
439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIGNUM        *tmp_1=NULL, *tmp_2=NULL;
440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *buffer_1=NULL, *buffer_2=NULL,
441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	              *a_buf=NULL, *b_buf=NULL;
442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t        len_1, len_2;
443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char char_zero = 0;
444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!group || !curve || !curve->a || !curve->b)
446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL)
449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* get a and b */
457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (nid == NID_X9_62_prime_field)
458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL))
460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
465392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_EC2M
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else	/* nid == NID_X9_62_characteristic_two_field */
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL))
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
474392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	len_1 = (size_t)BN_num_bytes(tmp_1);
476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	len_2 = (size_t)BN_num_bytes(tmp_2);
477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (len_1 == 0)
479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* len_1 == 0 => a == 0 */
481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		a_buf = &char_zero;
482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		len_1 = 1;
483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL)
487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2CURVE,
489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			      ERR_R_MALLOC_FAILURE);
490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ( (len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0)
493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		a_buf = buffer_1;
498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (len_2 == 0)
501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* len_2 == 0 => b == 0 */
503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b_buf = &char_zero;
504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		len_2 = 1;
505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL)
509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2CURVE,
511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			      ERR_R_MALLOC_FAILURE);
512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ( (len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0)
515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b_buf = buffer_2;
520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* set a and b */
523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2))
525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* set the seed (optional) */
531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group->seed)
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!curve->seed)
534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if ((curve->seed = ASN1_BIT_STRING_new()) == NULL)
535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		                         (int)group->seed_len))
543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (curve->seed)
551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ASN1_BIT_STRING_free(curve->seed);
553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			curve->seed = NULL;
554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok = 1;
558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:	if (buffer_1)
560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(buffer_1);
561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (buffer_2)
562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(buffer_2);
563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (tmp_1)
564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(tmp_1);
565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (tmp_2)
566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(tmp_2);
567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ok);
568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group,
571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                              ECPARAMETERS *param)
572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	ok=0;
574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t  len=0;
575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ECPARAMETERS   *ret=NULL;
576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIGNUM	       *tmp=NULL;
577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char  *buffer=NULL;
578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const EC_POINT *point=NULL;
579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	point_conversion_form_t form;
580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((tmp = BN_new()) == NULL)
582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (param == NULL)
588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((ret = ECPARAMETERS_new()) == NULL)
590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS,
592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			      ERR_R_MALLOC_FAILURE);
593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = param;
598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* set the version (always one) */
600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret->version = (long)0x1;
601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* set the fieldID */
603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!ec_asn1_group2fieldid(group, ret->fieldID))
604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* set the curve */
610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!ec_asn1_group2curve(group, ret->curve))
611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* set the base point */
617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((point = EC_GROUP_get0_generator(group)) == NULL)
618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
620656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	form = EC_GROUP_get_point_conversion_form(group);
624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (len == 0)
627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((buffer = OPENSSL_malloc(len)) == NULL)
632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL))
637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL)
642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!ASN1_OCTET_STRING_set(ret->base, buffer, len))
647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
650656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* set the order */
653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!EC_GROUP_get_order(group, tmp, NULL))
654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret->order == NULL)
660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
662656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* set the cofactor (optional) */
666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (EC_GROUP_get_cofactor(group, tmp, NULL))
667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret->cofactor == NULL)
670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
675656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok = 1;
677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr :	if(!ok)
679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
680656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret && !param)
681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECPARAMETERS_free(ret);
682656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = NULL;
683656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (tmp)
685656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(tmp);
686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (buffer)
687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(buffer);
688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
690656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
691656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                           ECPKPARAMETERS *params)
693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int            ok = 1, tmp;
695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ECPKPARAMETERS *ret = params;
696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret == NULL)
698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((ret = ECPKPARAMETERS_new()) == NULL)
700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS,
702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			      ERR_R_MALLOC_FAILURE);
703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return NULL;
704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret->type == 0 && ret->value.named_curve)
709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ASN1_OBJECT_free(ret->value.named_curve);
710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (ret->type == 1 && ret->value.parameters)
711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECPARAMETERS_free(ret->value.parameters);
712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (EC_GROUP_get_asn1_flag(group))
715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* use the asn1 OID to describe the
717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * the elliptic curve parameters
718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 */
719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		tmp = EC_GROUP_get_curve_name(group);
720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (tmp)
721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret->type = 0;
723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ok = 0;
725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
727656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* we don't kmow the nid => ERROR */
728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ok = 0;
729656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
732656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* use the ECPARAMETERS structure */
733656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret->type = 1;
734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((ret->value.parameters = ec_asn1_group2parameters(
735656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		     group, NULL)) == NULL)
736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ok = 0;
737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
738656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
739656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!ok)
740656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
741656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECPKPARAMETERS_free(ret);
742656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
743656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
744656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
745656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
746656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
747656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
748656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
749656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int			ok = 0, tmp;
750656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EC_GROUP		*ret = NULL;
751656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIGNUM			*p = NULL, *a = NULL, *b = NULL;
752656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EC_POINT		*point=NULL;
753656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long    		field_bits;
754656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
755656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!params->fieldID || !params->fieldID->fieldType ||
756656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    !params->fieldID->p.ptr)
757656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
758656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
759656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
760656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
761656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
762656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* now extract the curve parameters a and b */
763656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!params->curve || !params->curve->a ||
764656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    !params->curve->a->data || !params->curve->b ||
765656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    !params->curve->b->data)
766656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
767656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
768656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
769656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
770656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
771656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (a == NULL)
772656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
773656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
774656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
775656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
776656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
777656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b == NULL)
778656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
779656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
780656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
781656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
782656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
783656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* get the field parameters */
784656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	tmp = OBJ_obj2nid(params->fieldID->fieldType);
785656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (tmp == NID_X9_62_characteristic_two_field)
786392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_NO_EC2M
787392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
788392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED);
789392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		goto err;
790392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
791392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else
792656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
793656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X9_62_CHARACTERISTIC_TWO *char_two;
794656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
795656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		char_two = params->fieldID->p.char_two;
796656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
797656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		field_bits = char_two->m;
798656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
799656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
800656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
801656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
802656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
803656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
804656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((p = BN_new()) == NULL)
805656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
806656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
807656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
808656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
809656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
810656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* get the base type */
811656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		tmp = OBJ_obj2nid(char_two->type);
812656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
813656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (tmp ==  NID_X9_62_tpBasis)
814656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
815656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			long tmp_long;
816656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
817656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!char_two->p.tpBasis)
818656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
819656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
820656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
821656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
822656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
823656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
824656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
825656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!(char_two->m > tmp_long && tmp_long > 0))
826656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
827656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS);
828656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
829656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
830656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
831656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* create the polynomial */
832656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!BN_set_bit(p, (int)char_two->m))
833656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
834656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!BN_set_bit(p, (int)tmp_long))
835656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
836656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!BN_set_bit(p, 0))
837656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
838656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
839656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (tmp == NID_X9_62_ppBasis)
840656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
841656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X9_62_PENTANOMIAL *penta;
842656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
843656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			penta = char_two->p.ppBasis;
844656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!penta)
845656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
846656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
847656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
848656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
849656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
850656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0))
851656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
852656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS);
853656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
854656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
855656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
856656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* create the polynomial */
857656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!BN_set_bit(p, (int)char_two->m)) goto err;
858656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!BN_set_bit(p, (int)penta->k1)) goto err;
859656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!BN_set_bit(p, (int)penta->k2)) goto err;
860656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!BN_set_bit(p, (int)penta->k3)) goto err;
861656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!BN_set_bit(p, 0)) goto err;
862656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
863656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (tmp == NID_X9_62_onBasis)
864656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
865656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
866656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
867656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
868656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else /* error */
869656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
870656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
871656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
872656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
873656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
874656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* create the EC_GROUP structure */
875656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
876656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
877392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
878656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (tmp == NID_X9_62_prime_field)
879656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
880656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* we have a curve over a prime field */
881656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* extract the prime number */
882656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!params->fieldID->p.prime)
883656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
884656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
885656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
886656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
887656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
888656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (p == NULL)
889656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
890656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
891656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
892656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
893656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
894656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (BN_is_negative(p) || BN_is_zero(p))
895656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
896656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
897656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
898656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
899656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
900656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		field_bits = BN_num_bits(p);
901656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
902656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
903656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
904656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
905656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
906656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
907656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* create the EC_GROUP structure */
908656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
909656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
910656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
911656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
912656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
913656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
914656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
915656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
916656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret == NULL)
917656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
918656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
919656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
920656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
921656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
922656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* extract seed (optional) */
923656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (params->curve->seed != NULL)
924656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
925656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret->seed != NULL)
926656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			OPENSSL_free(ret->seed);
927656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length)))
928656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
929656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
930656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			      ERR_R_MALLOC_FAILURE);
931656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
932656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
933656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy(ret->seed, params->curve->seed->data,
934656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		       params->curve->seed->length);
935656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret->seed_len = params->curve->seed->length;
936656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
937656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
938656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!params->order || !params->base || !params->base->data)
939656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
940656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
941656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
942656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
943656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
944656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((point = EC_POINT_new(ret)) == NULL) goto err;
945656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
946656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* set the point conversion form */
947656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
948656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				(params->base->data[0] & ~0x01));
949656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
950656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* extract the ec point */
951656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!EC_POINT_oct2point(ret, point, params->base->data,
952656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		                params->base->length, NULL))
953656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
954656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
955656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
956656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
957656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
958656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* extract the order */
959656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL)
960656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
961656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
962656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
963656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
964656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (BN_is_negative(a) || BN_is_zero(a))
965656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
966656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
967656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
968656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
969656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (BN_num_bits(a) > (int)field_bits + 1) /* Hasse bound */
970656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
971656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
972656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
973656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
974656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
975656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* extract the cofactor (optional) */
976656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (params->cofactor == NULL)
977656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
978656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b)
979656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
980656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BN_free(b);
981656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			b = NULL;
982656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
983656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
984656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
985656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL)
986656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
987656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
988656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
989656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
990656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* set the generator, order and cofactor (if present) */
991656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!EC_GROUP_set_generator(ret, point, a, b))
992656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
993656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
994656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
995656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
996656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
997656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok = 1;
998656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
999656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:	if (!ok)
1000656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1001656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret)
1002656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EC_GROUP_clear_free(ret);
1003656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = NULL;
1004656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1005656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1006656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (p)
1007656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(p);
1008656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (a)
1009656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(a);
1010656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b)
1011656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(b);
1012656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (point)
1013656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EC_POINT_free(point);
1014656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
1015656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1016656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1017656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectEC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
1018656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1019656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EC_GROUP *ret=NULL;
1020656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int      tmp=0;
1021656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1022656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (params == NULL)
1023656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1024656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
1025656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		      EC_R_MISSING_PARAMETERS);
1026656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
1027656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1028656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1029656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (params->type == 0)
1030656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{ /* the curve is given by an OID */
1031656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		tmp = OBJ_obj2nid(params->value.named_curve);
1032656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL)
1033656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1034656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
1035656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			      EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
1036656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return NULL;
1037656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1038656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
1039656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1040656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (params->type == 1)
1041656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{ /* the parameters are given by a ECPARAMETERS
1042656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   * structure */
1043656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = ec_asn1_parameters2group(params->value.parameters);
1044656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!ret)
1045656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1046656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
1047656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return NULL;
1048656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1049656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EC_GROUP_set_asn1_flag(ret, 0x0);
1050656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1051656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (params->type == 2)
1052656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{ /* implicitlyCA */
1053656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
1054656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1055656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
1056656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1057656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
1058656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
1059656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1060656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1061656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
1062656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1063656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1064656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
1065656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1066656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectEC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
1067656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1068656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EC_GROUP	*group  = NULL;
1069656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ECPKPARAMETERS	*params = NULL;
1070656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1071656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL)
1072656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1073656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
1074656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECPKPARAMETERS_free(params);
1075656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
1076656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1077656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1078656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((group = ec_asn1_pkparameters2group(params)) == NULL)
1079656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1080656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
1081392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ECPKPARAMETERS_free(params);
1082656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
1083656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1084656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1085656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1086656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (a && *a)
1087656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EC_GROUP_clear_free(*a);
1088656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (a)
1089656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*a = group;
1090656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1091656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ECPKPARAMETERS_free(params);
1092656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(group);
1093656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1094656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1095656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
1096656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1097656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int		ret=0;
1098656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ECPKPARAMETERS	*tmp = ec_asn1_group2pkparameters(a, NULL);
1099656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (tmp == NULL)
1100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
1102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
1103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0)
1105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
1107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECPKPARAMETERS_free(tmp);
1108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
1109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ECPKPARAMETERS_free(tmp);
1111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
1112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* some EC_KEY functions */
1115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectEC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
1117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int             ok=0;
1119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EC_KEY          *ret=NULL;
1120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EC_PRIVATEKEY   *priv_key=NULL;
1121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
1126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL)
1129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EC_PRIVATEKEY_free(priv_key);
1132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
1133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (a == NULL || *a == NULL)
1136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((ret = EC_KEY_new()) == NULL)
1138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_D2I_ECPRIVATEKEY,
1140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                 ERR_R_MALLOC_FAILURE);
1141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
1142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (a)
1144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*a = ret;
1145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
1147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = *a;
1148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (priv_key->parameters)
1150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret->group)
1152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EC_GROUP_clear_free(ret->group);
1153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret->group == NULL)
1157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret->version = priv_key->version;
1163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (priv_key->privateKey)
1165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret->priv_key = BN_bin2bn(
1167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			M_ASN1_STRING_data(priv_key->privateKey),
1168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			M_ASN1_STRING_length(priv_key->privateKey),
1169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret->priv_key);
1170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret->priv_key == NULL)
1171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_D2I_ECPRIVATEKEY,
1173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                              ERR_R_BN_LIB);
1174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
1175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
1178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_D2I_ECPRIVATEKEY,
1180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                      EC_R_MISSING_PRIVATE_KEY);
1181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (priv_key->publicKey)
1185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		const unsigned char *pub_oct;
1187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		size_t pub_oct_len;
1188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret->pub_key)
1190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EC_POINT_clear_free(ret->pub_key);
1191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret->pub_key = EC_POINT_new(ret->group);
1192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret->pub_key == NULL)
1193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
1196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		pub_oct     = M_ASN1_STRING_data(priv_key->publicKey);
1198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
1199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* save the point conversion form */
1200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
1201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			pub_oct, pub_oct_len, NULL))
1203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
1206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok = 1;
1210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
1211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!ok)
1212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ret)
1214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EC_KEY_free(ret);
1215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = NULL;
1216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (priv_key)
1219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EC_PRIVATEKEY_free(priv_key);
1220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
1222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint	i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
1225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int             ret=0, ok=0;
1227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char   *buffer=NULL;
1228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t          buf_len=0, tmp_len;
1229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EC_PRIVATEKEY   *priv_key=NULL;
1230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (a == NULL || a->group == NULL || a->priv_key == NULL)
1232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_I2D_ECPRIVATEKEY,
1234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                      ERR_R_PASSED_NULL_PARAMETER);
1235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_I2D_ECPRIVATEKEY,
1241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                      ERR_R_MALLOC_FAILURE);
1242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	priv_key->version = a->version;
1246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	buf_len = (size_t)BN_num_bytes(a->priv_key);
1248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	buffer = OPENSSL_malloc(buf_len);
1249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (buffer == NULL)
1250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_I2D_ECPRIVATEKEY,
1252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                      ERR_R_MALLOC_FAILURE);
1253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!BN_bn2bin(a->priv_key, buffer))
1257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
1259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len))
1263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS))
1269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((priv_key->parameters = ec_asn1_group2pkparameters(
1271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			a->group, priv_key->parameters)) == NULL)
1272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
1275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!(a->enc_flag & EC_PKEY_NO_PUBKEY))
1279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		priv_key->publicKey = M_ASN1_BIT_STRING_new();
1281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (priv_key->publicKey == NULL)
1282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_I2D_ECPRIVATEKEY,
1284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ERR_R_MALLOC_FAILURE);
1285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
1286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
1289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				a->conv_form, NULL, 0, NULL);
1290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (tmp_len > buf_len)
1292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
1294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!tmp_buffer)
1295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
1296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
1298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
1299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			buffer = tmp_buffer;
1300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			buf_len = tmp_len;
1301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!EC_POINT_point2oct(a->group, a->pub_key,
1304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			a->conv_form, buffer, buf_len, NULL))
1305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
1308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
1311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
1312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer,
1313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				buf_len))
1314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
1317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0)
1321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok=1;
1326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
1327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (buffer)
1328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(buffer);
1329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (priv_key)
1330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EC_PRIVATEKEY_free(priv_key);
1331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ok?ret:0);
1332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint i2d_ECParameters(EC_KEY *a, unsigned char **out)
1335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (a == NULL)
1337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
1340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return i2d_ECPKParameters(a->group, out);
1342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectEC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
1345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EC_KEY   *ret;
1347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (in == NULL || *in == NULL)
1349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
1352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (a == NULL || *a == NULL)
1355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((ret = EC_KEY_new()) == NULL)
1357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
1359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return NULL;
1360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (a)
1362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*a = ret;
1363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
1365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = *a;
1366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!d2i_ECPKParameters(&ret->group, in, len))
1368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
1370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return NULL;
1371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
1374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectEC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
1377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EC_KEY *ret=NULL;
1379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (a == NULL || (*a) == NULL || (*a)->group == NULL)
1381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* sorry, but a EC_GROUP-structur is necessary
1383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                 * to set the public key */
1384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
1386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = *a;
1388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret->pub_key == NULL &&
1389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(ret->pub_key = EC_POINT_new(ret->group)) == NULL)
1390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
1393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL))
1395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
1397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
1398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* save the point conversion form */
1400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01);
1401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*in += len;
1402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
1403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
1406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        size_t buf_len=0;
1408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int new_buffer = 0;
1409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        if (a == NULL)
1411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
1414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        buf_len = EC_POINT_point2oct(a->group, a->pub_key,
1417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                              a->conv_form, NULL, 0, NULL);
1418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (out == NULL || buf_len == 0)
1420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* out == NULL => just return the length of the octet string */
1421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return buf_len;
1422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (*out == NULL)
1424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((*out = OPENSSL_malloc(buf_len)) == NULL)
1426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
1429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		new_buffer = 1;
1431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				*out, buf_len, NULL))
1434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
1436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(*out);
1437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*out = NULL;
1438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
1439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!new_buffer)
1441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*out += buf_len;
1442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return buf_len;
1443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1444