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