/src/openssl/crypto/bn/bn_mpi.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 1995-2020 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 | 8.95k | { |
16 | 8.95k | int bits; |
17 | 8.95k | int num = 0; |
18 | 8.95k | int ext = 0; |
19 | 8.95k | long l; |
20 | | |
21 | 8.95k | bits = BN_num_bits(a); |
22 | 8.95k | num = (bits + 7) / 8; |
23 | 8.95k | if (bits > 0) { |
24 | 6.79k | ext = ((bits & 0x07) == 0); |
25 | 6.79k | } |
26 | 8.95k | if (d == NULL) |
27 | 4.47k | return (num + 4 + ext); |
28 | | |
29 | 4.47k | l = num + ext; |
30 | 4.47k | d[0] = (unsigned char)(l >> 24) & 0xff; |
31 | 4.47k | d[1] = (unsigned char)(l >> 16) & 0xff; |
32 | 4.47k | d[2] = (unsigned char)(l >> 8) & 0xff; |
33 | 4.47k | d[3] = (unsigned char)(l) & 0xff; |
34 | 4.47k | if (ext) |
35 | 1.28k | d[4] = 0; |
36 | 4.47k | num = BN_bn2bin(a, &(d[4 + ext])); |
37 | 4.47k | if (a->neg) |
38 | 12 | d[4] |= 0x80; |
39 | 4.47k | return (num + 4 + ext); |
40 | 8.95k | } |
41 | | |
42 | | BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain) |
43 | 4.47k | { |
44 | 4.47k | long len; |
45 | 4.47k | int neg = 0; |
46 | 4.47k | BIGNUM *a = NULL; |
47 | | |
48 | 4.47k | if (n < 4 || (d[0] & 0x80) != 0) { |
49 | 0 | ERR_raise(ERR_LIB_BN, BN_R_INVALID_LENGTH); |
50 | 0 | return NULL; |
51 | 0 | } |
52 | 4.47k | len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | (int) |
53 | 4.47k | d[3]; |
54 | 4.47k | if ((len + 4) != n) { |
55 | 0 | ERR_raise(ERR_LIB_BN, BN_R_ENCODING_ERROR); |
56 | 0 | return NULL; |
57 | 0 | } |
58 | | |
59 | 4.47k | if (ain == NULL) |
60 | 0 | a = BN_new(); |
61 | 4.47k | else |
62 | 4.47k | a = ain; |
63 | | |
64 | 4.47k | if (a == NULL) |
65 | 0 | return NULL; |
66 | | |
67 | 4.47k | if (len == 0) { |
68 | 1.08k | a->neg = 0; |
69 | 1.08k | a->top = 0; |
70 | 1.08k | return a; |
71 | 1.08k | } |
72 | 3.39k | d += 4; |
73 | 3.39k | if ((*d) & 0x80) |
74 | 12 | neg = 1; |
75 | 3.39k | if (BN_bin2bn(d, (int)len, a) == NULL) { |
76 | 0 | if (ain == NULL) |
77 | 0 | BN_free(a); |
78 | 0 | return NULL; |
79 | 0 | } |
80 | 3.39k | a->neg = neg; |
81 | 3.39k | if (neg) { |
82 | 12 | BN_clear_bit(a, BN_num_bits(a) - 1); |
83 | 12 | } |
84 | 3.39k | bn_check_top(a); |
85 | 3.39k | return a; |
86 | 3.39k | } |