Add missing include of cryptlib.h
[openssl.git] / crypto / asn1 / x_int64.c
1 /*
2  * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 "internal/numbers.h"
13 #include <openssl/asn1t.h>
14 #include <openssl/bn.h>
15 #include "asn1_locl.h"
16
17 /*
18  * Custom primitive types for handling int32_t, int64_t, uint32_t, uint64_t.
19  * This converts between an ASN1_INTEGER and those types directly.
20  * This is preferred to using the LONG / ZLONG primitives.
21  */
22
23 /*
24  * We abuse the ASN1_ITEM fields |size| as a flags field
25  */
26 #define INTxx_FLAG_ZERO_DEFAULT (1<<0)
27 #define INTxx_FLAG_SIGNED       (1<<1)
28
29 static int uint64_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
30 {
31     *pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint64_t));
32     if (*pval == NULL)
33         return 0;
34     return 1;
35 }
36
37 static void uint64_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
38 {
39     OPENSSL_free(*pval);
40     *pval = NULL;
41 }
42
43 static void uint64_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
44 {
45     **(uint64_t **)pval = 0;
46 }
47
48 static int uint64_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
49                     const ASN1_ITEM *it)
50 {
51     uint64_t utmp;
52     int neg = 0;
53     /* this exists to bypass broken gcc optimization */
54     char *cp = (char *)*pval;
55
56     /* use memcpy, because we may not be uint64_t aligned */
57     memcpy(&utmp, cp, sizeof(utmp));
58
59     if ((it->size & INTxx_FLAG_ZERO_DEFAULT) == INTxx_FLAG_ZERO_DEFAULT
60         && utmp == 0)
61         return -1;
62     if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
63         && (int64_t)utmp < 0) {
64         /* i2c_uint64_int() assumes positive values */
65         utmp = 0 - utmp;
66         neg = 1;
67     }
68
69     return i2c_uint64_int(cont, utmp, neg);
70 }
71
72 static int uint64_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
73                     int utype, char *free_cont, const ASN1_ITEM *it)
74 {
75     uint64_t utmp = 0;
76     char *cp;
77     int neg = 0;
78
79     if (*pval == NULL && !uint64_new(pval, it))
80         return 0;
81
82     cp = (char *)*pval;
83     if (!c2i_uint64_int(&utmp, &neg, &cont, len))
84         return 0;
85     if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) {
86         ASN1err(ASN1_F_UINT64_C2I, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
87         return 0;
88     }
89     if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
90             && !neg && utmp > INT64_MAX) {
91         ASN1err(ASN1_F_UINT64_C2I, ASN1_R_TOO_LARGE);
92         return 0;
93     }
94     if (neg)
95         /* c2i_uint64_int() returns positive values */
96         utmp = 0 - utmp;
97     memcpy(cp, &utmp, sizeof(utmp));
98     return 1;
99 }
100
101 static int uint64_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
102                         int indent, const ASN1_PCTX *pctx)
103 {
104     if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED)
105         return BIO_printf(out, "%jd\n", **(int64_t **)pval);
106     return BIO_printf(out, "%ju\n", **(uint64_t **)pval);
107 }
108
109 /* 32-bit variants */
110
111 static int uint32_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
112 {
113     *pval = (ASN1_VALUE *)OPENSSL_zalloc(sizeof(uint32_t));
114     if (*pval == NULL)
115         return 0;
116     return 1;
117 }
118
119 static void uint32_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
120 {
121     OPENSSL_free(*pval);
122     *pval = NULL;
123 }
124
125 static void uint32_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
126 {
127     **(uint32_t **)pval = 0;
128 }
129
130 static int uint32_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
131                     const ASN1_ITEM *it)
132 {
133     uint32_t utmp;
134     int neg = 0;
135     /* this exists to bypass broken gcc optimization */
136     char *cp = (char *)*pval;
137
138     /* use memcpy, because we may not be uint32_t aligned */
139     memcpy(&utmp, cp, sizeof(utmp));
140
141     if ((it->size & INTxx_FLAG_ZERO_DEFAULT) == INTxx_FLAG_ZERO_DEFAULT
142         && utmp == 0)
143         return -1;
144     if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED
145         && (int32_t)utmp < 0) {
146         /* i2c_uint64_int() assumes positive values */
147         utmp = 0 - utmp;
148         neg = 1;
149     }
150
151     return i2c_uint64_int(cont, (uint64_t)utmp, neg);
152 }
153
154 /*
155  * Absolute value of INT32_MIN: we can't just use -INT32_MIN as it produces
156  * overflow warnings.
157  */
158
159 #define ABS_INT32_MIN ((uint32_t)INT32_MAX + 1)
160
161 static int uint32_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
162                     int utype, char *free_cont, const ASN1_ITEM *it)
163 {
164     uint64_t utmp = 0;
165     uint32_t utmp2 = 0;
166     char *cp;
167     int neg = 0;
168
169     if (*pval == NULL && !uint64_new(pval, it))
170         return 0;
171
172     cp = (char *)*pval;
173     if (!c2i_uint64_int(&utmp, &neg, &cont, len))
174         return 0;
175     if ((it->size & INTxx_FLAG_SIGNED) == 0 && neg) {
176         ASN1err(ASN1_F_UINT32_C2I, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
177         return 0;
178     }
179     if (neg) {
180         if (utmp > ABS_INT32_MIN) {
181             ASN1err(ASN1_F_UINT32_C2I, ASN1_R_TOO_SMALL);
182             return 0;
183         }
184         utmp = 0 - utmp;
185     } else {
186         if (((it->size & INTxx_FLAG_SIGNED) != 0 && utmp > INT32_MAX)
187             || ((it->size & INTxx_FLAG_SIGNED) == 0 && utmp > UINT32_MAX)) {
188             ASN1err(ASN1_F_UINT32_C2I, ASN1_R_TOO_LARGE);
189             return 0;
190         }
191     }
192     utmp2 = (uint32_t)utmp;
193     memcpy(cp, &utmp2, sizeof(utmp2));
194     return 1;
195 }
196
197 static int uint32_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
198                         int indent, const ASN1_PCTX *pctx)
199 {
200     if ((it->size & INTxx_FLAG_SIGNED) == INTxx_FLAG_SIGNED)
201         return BIO_printf(out, "%d\n", **(int32_t **)pval);
202     return BIO_printf(out, "%u\n", **(uint32_t **)pval);
203 }
204
205
206 /* Define the primitives themselves */
207
208 static ASN1_PRIMITIVE_FUNCS uint32_pf = {
209     NULL, 0,
210     uint32_new,
211     uint32_free,
212     uint32_clear,
213     uint32_c2i,
214     uint32_i2c,
215     uint32_print
216 };
217
218 static ASN1_PRIMITIVE_FUNCS uint64_pf = {
219     NULL, 0,
220     uint64_new,
221     uint64_free,
222     uint64_clear,
223     uint64_c2i,
224     uint64_i2c,
225     uint64_print
226 };
227
228 ASN1_ITEM_start(INT32)
229     ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
230     INTxx_FLAG_SIGNED, "INT32"
231 ASN1_ITEM_end(INT32)
232
233 ASN1_ITEM_start(UINT32)
234     ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf, 0, "UINT32"
235 ASN1_ITEM_end(UINT32)
236
237 ASN1_ITEM_start(INT64)
238     ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
239     INTxx_FLAG_SIGNED, "INT64"
240 ASN1_ITEM_end(INT64)
241
242 ASN1_ITEM_start(UINT64)
243     ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf, 0, "UINT64"
244 ASN1_ITEM_end(UINT64)
245
246 ASN1_ITEM_start(ZINT32)
247     ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
248     INTxx_FLAG_ZERO_DEFAULT|INTxx_FLAG_SIGNED, "ZINT32"
249 ASN1_ITEM_end(ZINT32)
250
251 ASN1_ITEM_start(ZUINT32)
252     ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint32_pf,
253     INTxx_FLAG_ZERO_DEFAULT, "ZUINT32"
254 ASN1_ITEM_end(ZUINT32)
255
256 ASN1_ITEM_start(ZINT64)
257     ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
258     INTxx_FLAG_ZERO_DEFAULT|INTxx_FLAG_SIGNED, "ZINT64"
259 ASN1_ITEM_end(ZINT64)
260
261 ASN1_ITEM_start(ZUINT64)
262     ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &uint64_pf,
263     INTxx_FLAG_ZERO_DEFAULT, "ZUINT64"
264 ASN1_ITEM_end(ZUINT64)
265