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