1 | /* |
2 | * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. |
3 | * |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at |
7 | * https://www.openssl.org/source/license.html |
8 | */ |
9 | |
10 | #include <stdio.h> |
11 | #include "internal/cryptlib.h" |
12 | #include "bn_local.h" |
13 | |
14 | int BN_bn2mpi(const BIGNUM *a, unsigned char *d) |
15 | { |
16 | int bits; |
17 | int num = 0; |
18 | int ext = 0; |
19 | long l; |
20 | |
21 | bits = BN_num_bits(a); |
22 | num = (bits + 7) / 8; |
23 | if (bits > 0) { |
24 | ext = ((bits & 0x07) == 0); |
25 | } |
26 | if (d == NULL) |
27 | return (num + 4 + ext); |
28 | |
29 | l = num + ext; |
30 | d[0] = (unsigned char)(l >> 24) & 0xff; |
31 | d[1] = (unsigned char)(l >> 16) & 0xff; |
32 | d[2] = (unsigned char)(l >> 8) & 0xff; |
33 | d[3] = (unsigned char)(l) & 0xff; |
34 | if (ext) |
35 | d[4] = 0; |
36 | num = BN_bn2bin(a, &(d[4 + ext])); |
37 | if (a->neg) |
38 | d[4] |= 0x80; |
39 | return (num + 4 + ext); |
40 | } |
41 | |
42 | BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain) |
43 | { |
44 | long len; |
45 | int neg = 0; |
46 | BIGNUM *a = NULL; |
47 | |
48 | if (n < 4) { |
49 | BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH); |
50 | return NULL; |
51 | } |
52 | len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | (int) |
53 | d[3]; |
54 | if ((len + 4) != n) { |
55 | BNerr(BN_F_BN_MPI2BN, BN_R_ENCODING_ERROR); |
56 | return NULL; |
57 | } |
58 | |
59 | if (ain == NULL) |
60 | a = BN_new(); |
61 | else |
62 | a = ain; |
63 | |
64 | if (a == NULL) |
65 | return NULL; |
66 | |
67 | if (len == 0) { |
68 | a->neg = 0; |
69 | a->top = 0; |
70 | return a; |
71 | } |
72 | d += 4; |
73 | if ((*d) & 0x80) |
74 | neg = 1; |
75 | if (BN_bin2bn(d, (int)len, a) == NULL) { |
76 | if (ain == NULL) |
77 | BN_free(a); |
78 | return NULL; |
79 | } |
80 | a->neg = neg; |
81 | if (neg) { |
82 | BN_clear_bit(a, BN_num_bits(a) - 1); |
83 | } |
84 | bn_check_top(a); |
85 | return a; |
86 | } |
87 | |