1/*
2 * Copyright (c) 2011-12 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/* x_bignum.c */
24/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
25 * project 2000.
26 */
27/* ====================================================================
28 * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 *
34 * 1. Redistributions of source code must retain the above copyright
35 *    notice, this list of conditions and the following disclaimer.
36 *
37 * 2. Redistributions in binary form must reproduce the above copyright
38 *    notice, this list of conditions and the following disclaimer in
39 *    the documentation and/or other materials provided with the
40 *    distribution.
41 *
42 * 3. All advertising materials mentioning features or use of this
43 *    software must display the following acknowledgment:
44 *    "This product includes software developed by the OpenSSL Project
45 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
46 *
47 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
48 *    endorse or promote products derived from this software without
49 *    prior written permission. For written permission, please contact
50 *    licensing@OpenSSL.org.
51 *
52 * 5. Products derived from this software may not be called "OpenSSL"
53 *    nor may "OpenSSL" appear in their names without prior written
54 *    permission of the OpenSSL Project.
55 *
56 * 6. Redistributions of any form whatsoever must retain the following
57 *    acknowledgment:
58 *    "This product includes software developed by the OpenSSL Project
59 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
60 *
61 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
62 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
64 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
65 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
66 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
67 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
68 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
70 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
71 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
72 * OF THE POSSIBILITY OF SUCH DAMAGE.
73 * ====================================================================
74 *
75 * This product includes cryptographic software written by Eric Young
76 * (eay@cryptsoft.com).  This product includes software written by Tim
77 * Hudson (tjh@cryptsoft.com).
78 *
79 */
80
81#include <stdio.h>
82#include <stdlib.h>
83
84#if 0
85#include "cryptlib.h"
86#include <openssl/asn1t.h>
87#include <openssl/bn.h>
88
89#else
90
91#include "cs-asn1t.h"
92#include "cs-bn.h"
93#endif
94
95
96
97/* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a
98 * BIGNUM directly. Currently it ignores the sign which isn't a problem since all
99 * BIGNUMs used are non negative and anything that looks negative is normally due
100 * to an encoding error.
101 */
102
103#define BN_SENSITIVE	1
104
105static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
106static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
107
108static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
109static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
110
111static ASN1_PRIMITIVE_FUNCS bignum_pf = {
112	NULL, 0,
113	bn_new,
114	bn_free,
115	0,
116	bn_c2i,
117	bn_i2c
118};
119
120ASN1_ITEM_start(BIGNUM)
121	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
122ASN1_ITEM_end(BIGNUM)
123
124ASN1_ITEM_start(CBIGNUM)
125	ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
126ASN1_ITEM_end(CBIGNUM)
127
128static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
129{
130	*pval = (ASN1_VALUE *)BN_new();
131	if(*pval) return 1;
132	else return 0;
133}
134
135static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
136{
137	if(!*pval) return;
138	if(it->size & BN_SENSITIVE) BN_clear_free((BIGNUM *)*pval);
139	else BN_free((BIGNUM *)*pval);
140	*pval = NULL;
141}
142
143static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
144{
145	BIGNUM *bn;
146	int pad;
147	if(!*pval) return -1;
148	bn = (BIGNUM *)*pval;
149	/* If MSB set in an octet we need a padding byte */
150	if(BN_num_bits(bn) & 0x7) pad = 0;
151	else pad = 1;
152	if(cont) {
153		if(pad) *cont++ = 0;
154		BN_bn2bin(bn, cont);
155	}
156	return pad + BN_num_bytes(bn);
157}
158
159static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
160		  int utype, char *free_cont, const ASN1_ITEM *it)
161{
162	BIGNUM *bn;
163	if(!*pval) bn_new(pval, it);
164	bn  = (BIGNUM *)*pval;
165	if(!BN_bin2bn(cont, len, bn)) {
166		bn_free(pval, it);
167		return 0;
168	}
169	return 1;
170}
171
172
173