1 /* $NetBSD: bn.c,v 1.1.1.1 2011/04/13 18:14:49 elric Exp $ */
4 * Copyright (c) 2006 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 #include <krb5/krb5-types.h>
45 #include <krb5/roken.h>
46 #include <krb5/rfc2459_asn1.h> /* XXX */
57 hi
= calloc(1, sizeof(*hi
));
71 heim_integer
*hi
= (heim_integer
*)bn
;
73 memset(hi
->data
, 0, hi
->length
);
76 memset(hi
, 0, sizeof(*hi
));
80 BN_clear_free(BIGNUM
*bn
)
86 BN_dup(const BIGNUM
*bn
)
89 if (der_copy_heim_integer((const heim_integer
*)bn
, (heim_integer
*)b
)) {
97 * If the caller really want to know the number of bits used, subtract
98 * one from the length, multiply by 8, and then lookup in the table
99 * how many bits the hightest byte uses.
102 BN_num_bits(const BIGNUM
*bn
)
104 static unsigned char num2bits
[256] = {
105 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
106 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
107 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
108 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
109 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
110 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
111 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
112 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
114 const heim_integer
*i
= (const void *)bn
;
117 return (i
->length
- 1) * 8 + num2bits
[((unsigned char *)i
->data
)[0]];
121 BN_num_bytes(const BIGNUM
*bn
)
123 return ((const heim_integer
*)bn
)->length
;
127 * Ignore negative flag.
131 BN_bin2bn(const void *s
, int len
, BIGNUM
*bn
)
133 heim_integer
*hi
= (void *)bn
;
139 hi
= (heim_integer
*)BN_new();
144 BN_clear((BIGNUM
*)hi
);
146 hi
->data
= malloc(len
);
147 if (hi
->data
== NULL
&& len
!= 0) {
149 BN_free((BIGNUM
*)hi
);
153 memcpy(hi
->data
, s
, len
);
158 BN_bn2bin(const BIGNUM
*bn
, void *to
)
160 const heim_integer
*hi
= (const void *)bn
;
161 memcpy(to
, hi
->data
, hi
->length
);
166 BN_hex2bn(BIGNUM
**bnp
, const char *in
)
184 ret
= hex_decode(in
, data
, len
);
190 *bnp
= BN_bin2bn(data
, ret
, NULL
);
194 BN_set_negative(*bnp
, negative
);
199 BN_bn2hex(const BIGNUM
*bn
)
206 len
= BN_num_bytes(bn
);
211 len
= BN_bn2bin(bn
, data
);
213 ret
= hex_encode(data
, len
, &str
);
222 BN_cmp(const BIGNUM
*bn1
, const BIGNUM
*bn2
)
224 return der_heim_integer_cmp((const heim_integer
*)bn1
,
225 (const heim_integer
*)bn2
);
229 BN_set_negative(BIGNUM
*bn
, int flag
)
231 ((heim_integer
*)bn
)->negative
= (flag
? 1 : 0);
235 BN_is_negative(const BIGNUM
*bn
)
237 return ((const heim_integer
*)bn
)->negative
? 1 : 0;
240 static const unsigned char is_set
[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
243 BN_is_bit_set(const BIGNUM
*bn
, int bit
)
245 heim_integer
*hi
= (heim_integer
*)bn
;
246 unsigned char *p
= hi
->data
;
248 if ((bit
/ 8) > hi
->length
|| hi
->length
== 0)
251 return p
[hi
->length
- 1 - (bit
/ 8)] & is_set
[bit
% 8];
255 BN_set_bit(BIGNUM
*bn
, int bit
)
257 heim_integer
*hi
= (heim_integer
*)bn
;
260 if ((bit
/ 8) > hi
->length
|| hi
->length
== 0) {
261 size_t len
= (bit
+ 7) / 8;
262 void *d
= realloc(hi
->data
, len
);
267 memset(&p
[hi
->length
], 0, len
);
272 p
[hi
->length
- 1 - (bit
/ 8)] |= is_set
[bit
% 8];
277 BN_clear_bit(BIGNUM
*bn
, int bit
)
279 heim_integer
*hi
= (heim_integer
*)bn
;
280 unsigned char *p
= hi
->data
;
282 if ((bit
/ 8) > hi
->length
|| hi
->length
== 0)
285 p
[hi
->length
- 1 - (bit
/ 8)] &= (unsigned char)(~(is_set
[bit
% 8]));
291 BN_set_word(BIGNUM
*bn
, unsigned long num
)
293 unsigned char p
[sizeof(num
)];
297 for (num2
= num
, i
= 0; num2
> 0; i
++)
302 p
[i
- 1] = (num
& 0xff);
306 bn
= BN_bin2bn(p
, len
, bn
);
311 BN_get_word(const BIGNUM
*bn
)
313 heim_integer
*hi
= (heim_integer
*)bn
;
314 unsigned long num
= 0;
317 if (hi
->negative
|| hi
->length
> sizeof(num
))
320 for (i
= 0; i
< hi
->length
; i
++)
321 num
= ((unsigned char *)hi
->data
)[i
] | (num
<< 8);
326 BN_rand(BIGNUM
*bn
, int bits
, int top
, int bottom
)
328 size_t len
= (bits
+ 7) / 8;
329 heim_integer
*i
= (heim_integer
*)bn
;
334 i
->data
= malloc(len
);
335 if (i
->data
== NULL
&& len
!= 0)
339 if (RAND_bytes(i
->data
, i
->length
) != 1) {
348 BN_clear_bit(bn
, j
- 1);
355 } else if (top
== 0 && bits
> 0) {
356 BN_set_bit(bn
, bits
- 1);
357 } else if (top
== 1 && bits
> 1) {
358 BN_set_bit(bn
, bits
- 1);
359 BN_set_bit(bn
, bits
- 2);
365 if (bottom
&& bits
> 0)
376 BN_uadd(BIGNUM
*res
, const BIGNUM
*a
, const BIGNUM
*b
)
378 const heim_integer
*ai
= (const heim_integer
*)a
;
379 const heim_integer
*bi
= (const heim_integer
*)b
;
380 const unsigned char *ap
, *bp
;
386 if (ai
->negative
&& bi
->negative
)
388 if (ai
->length
< bi
->length
) {
389 const heim_integer
*si
= bi
;
394 ci
.length
= ai
->length
+ 1;
395 ci
.data
= malloc(ci
.length
);
399 ap
= &((const unsigned char *)ai
->data
)[ai
->length
- 1];
400 bp
= &((const unsigned char *)bi
->data
)[bi
->length
- 1];
401 cp
= &((unsigned char *)ci
.data
)[ci
.length
- 1];
403 for (len
= bi
->length
; len
> 0; len
--) {
404 carry
= *ap
+ *bp
+ carry
;
406 carry
= (carry
& ~0xff) ? 1 : 0;
409 for (len
= ai
->length
- bi
->length
; len
> 0; len
--) {
412 carry
= (carry
& ~0xff) ? 1 : 0;
416 memmove(cp
, cp
+ 1, --ci
.length
);
421 *((heim_integer
*)res
) = ci
;
428 * Callback when doing slow generation of numbers, like primes.
432 BN_GENCB_set(BN_GENCB
*gencb
, int (*cb_2
)(int, int, BN_GENCB
*), void *ctx
)
435 gencb
->cb
.cb_2
= cb_2
;
440 BN_GENCB_call(BN_GENCB
*cb
, int a
, int b
)
442 if (cb
== NULL
|| cb
->cb
.cb_2
== NULL
)
444 return cb
->cb
.cb_2(a
, b
, cb
);
468 c
= calloc(1, sizeof(*c
));
473 BN_CTX_free(BN_CTX
*c
)
476 for (i
= 0; i
< c
->bn
.len
; i
++)
477 BN_free(c
->bn
.val
[i
]);
483 BN_CTX_get(BN_CTX
*c
)
485 if (c
->bn
.used
== c
->bn
.len
) {
489 ptr
= realloc(c
->bn
.val
, c
->bn
.len
* sizeof(c
->bn
.val
[0]));
493 for (i
= c
->bn
.used
; i
< c
->bn
.len
; i
++) {
494 c
->bn
.val
[i
] = BN_new();
495 if (c
->bn
.val
[i
] == NULL
) {
501 return c
->bn
.val
[c
->bn
.used
++];
505 BN_CTX_start(BN_CTX
*c
)
507 if (c
->stack
.used
== c
->stack
.len
) {
510 ptr
= realloc(c
->stack
.val
, c
->stack
.len
* sizeof(c
->stack
.val
[0]));
515 c
->stack
.val
[c
->stack
.used
++] = c
->bn
.used
;
519 BN_CTX_end(BN_CTX
*c
)
521 const size_t prev
= c
->stack
.val
[c
->stack
.used
- 1];
524 if (c
->stack
.used
== 0)
527 for (i
= prev
; i
< c
->bn
.used
; i
++)
528 BN_clear(c
->bn
.val
[i
]);