]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
2039c421 | 2 | * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. |
e76f935e | 3 | * |
365a2d99 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
2039c421 RS |
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 | |
e76f935e DSH |
8 | */ |
9 | ||
10 | #include <stdio.h> | |
b39fc560 | 11 | #include "internal/cryptlib.h" |
9d6b1ce6 | 12 | #include <openssl/asn1t.h> |
0f814687 | 13 | #include <openssl/bn.h> |
e76f935e | 14 | |
0f113f3e MC |
15 | /* |
16 | * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER | |
17 | * as a BIGNUM directly. Currently it ignores the sign which isn't a problem | |
18 | * since all BIGNUMs used are non negative and anything that looks negative | |
19 | * is normally due to an encoding error. | |
e76f935e DSH |
20 | */ |
21 | ||
0f113f3e | 22 | #define BN_SENSITIVE 1 |
e76f935e | 23 | |
9d6b1ce6 | 24 | static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it); |
74924dcb | 25 | static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it); |
9d6b1ce6 | 26 | static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it); |
e76f935e | 27 | |
9fdcc21f | 28 | static int bn_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype, |
0f113f3e MC |
29 | const ASN1_ITEM *it); |
30 | static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, | |
31 | int utype, char *free_cont, const ASN1_ITEM *it); | |
74924dcb RS |
32 | static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, |
33 | int utype, char *free_cont, const ASN1_ITEM *it); | |
9fdcc21f | 34 | static int bn_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, |
3cea73a7 | 35 | int indent, const ASN1_PCTX *pctx); |
e76f935e | 36 | |
9d6b1ce6 | 37 | static ASN1_PRIMITIVE_FUNCS bignum_pf = { |
0f113f3e MC |
38 | NULL, 0, |
39 | bn_new, | |
40 | bn_free, | |
41 | 0, | |
42 | bn_c2i, | |
3cea73a7 DSH |
43 | bn_i2c, |
44 | bn_print | |
9d6b1ce6 | 45 | }; |
e76f935e | 46 | |
74924dcb RS |
47 | static ASN1_PRIMITIVE_FUNCS cbignum_pf = { |
48 | NULL, 0, | |
49 | bn_secure_new, | |
50 | bn_free, | |
51 | 0, | |
52 | bn_secure_c2i, | |
3cea73a7 DSH |
53 | bn_i2c, |
54 | bn_print | |
74924dcb RS |
55 | }; |
56 | ||
bb5ea36b | 57 | ASN1_ITEM_start(BIGNUM) |
0f113f3e | 58 | ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM" |
d339187b | 59 | ASN1_ITEM_end(BIGNUM) |
bb5ea36b DSH |
60 | |
61 | ASN1_ITEM_start(CBIGNUM) | |
74924dcb | 62 | ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &cbignum_pf, BN_SENSITIVE, "CBIGNUM" |
d339187b | 63 | ASN1_ITEM_end(CBIGNUM) |
9d6b1ce6 DSH |
64 | |
65 | static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it) | |
66 | { | |
437b14b5 | 67 | *pval = (ASN1_VALUE *)BN_new(); |
90945fa3 | 68 | if (*pval != NULL) |
437b14b5 DSH |
69 | return 1; |
70 | else | |
71 | return 0; | |
9d6b1ce6 DSH |
72 | } |
73 | ||
74924dcb RS |
74 | static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it) |
75 | { | |
76 | *pval = (ASN1_VALUE *)BN_secure_new(); | |
90945fa3 | 77 | if (*pval != NULL) |
74924dcb RS |
78 | return 1; |
79 | else | |
80 | return 0; | |
81 | } | |
82 | ||
9d6b1ce6 DSH |
83 | static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it) |
84 | { | |
12a765a5 | 85 | if (*pval == NULL) |
437b14b5 DSH |
86 | return; |
87 | if (it->size & BN_SENSITIVE) | |
88 | BN_clear_free((BIGNUM *)*pval); | |
89 | else | |
90 | BN_free((BIGNUM *)*pval); | |
91 | *pval = NULL; | |
9d6b1ce6 | 92 | } |
e76f935e | 93 | |
9fdcc21f | 94 | static int bn_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype, |
437b14b5 | 95 | const ASN1_ITEM *it) |
e76f935e | 96 | { |
437b14b5 DSH |
97 | BIGNUM *bn; |
98 | int pad; | |
12a765a5 | 99 | if (*pval == NULL) |
437b14b5 DSH |
100 | return -1; |
101 | bn = (BIGNUM *)*pval; | |
102 | /* If MSB set in an octet we need a padding byte */ | |
103 | if (BN_num_bits(bn) & 0x7) | |
104 | pad = 0; | |
105 | else | |
106 | pad = 1; | |
107 | if (cont) { | |
108 | if (pad) | |
109 | *cont++ = 0; | |
110 | BN_bn2bin(bn, cont); | |
111 | } | |
112 | return pad + BN_num_bytes(bn); | |
e76f935e DSH |
113 | } |
114 | ||
875a644a | 115 | static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, |
0f113f3e | 116 | int utype, char *free_cont, const ASN1_ITEM *it) |
e76f935e | 117 | { |
437b14b5 | 118 | BIGNUM *bn; |
74924dcb | 119 | |
a7e974c7 | 120 | if (*pval == NULL && !bn_new(pval, it)) |
121 | return 0; | |
437b14b5 DSH |
122 | bn = (BIGNUM *)*pval; |
123 | if (!BN_bin2bn(cont, len, bn)) { | |
124 | bn_free(pval, it); | |
125 | return 0; | |
126 | } | |
127 | return 1; | |
e76f935e | 128 | } |
74924dcb RS |
129 | |
130 | static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, | |
131 | int utype, char *free_cont, const ASN1_ITEM *it) | |
132 | { | |
311e903d CPG |
133 | int ret; |
134 | BIGNUM *bn; | |
135 | ||
12a765a5 | 136 | if (*pval == NULL && !bn_secure_new(pval, it)) |
311e903d CPG |
137 | return 0; |
138 | ||
139 | ret = bn_c2i(pval, cont, len, utype, free_cont, it); | |
140 | if (!ret) | |
141 | return 0; | |
142 | ||
143 | /* Set constant-time flag for all secure BIGNUMS */ | |
144 | bn = (BIGNUM *)*pval; | |
145 | BN_set_flags(bn, BN_FLG_CONSTTIME); | |
146 | return ret; | |
74924dcb | 147 | } |
3cea73a7 | 148 | |
9fdcc21f | 149 | static int bn_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it, |
3cea73a7 DSH |
150 | int indent, const ASN1_PCTX *pctx) |
151 | { | |
152 | if (!BN_print(out, *(BIGNUM **)pval)) | |
153 | return 0; | |
154 | if (BIO_puts(out, "\n") <= 0) | |
155 | return 0; | |
156 | return 1; | |
157 | } |