xref: /aosp_15_r20/external/boringssl/src/crypto/asn1/a_int.c (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1 /* Copyright (C) 1995-1998 Eric Young ([email protected])
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young ([email protected]).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson ([email protected]).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young ([email protected])"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson ([email protected])"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/asn1.h>
58 
59 #include <assert.h>
60 #include <limits.h>
61 #include <string.h>
62 
63 #include <openssl/bytestring.h>
64 #include <openssl/err.h>
65 #include <openssl/mem.h>
66 
67 #include "../internal.h"
68 
69 
ASN1_INTEGER_dup(const ASN1_INTEGER * x)70 ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) {
71   return ASN1_STRING_dup(x);
72 }
73 
ASN1_INTEGER_cmp(const ASN1_INTEGER * x,const ASN1_INTEGER * y)74 int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) {
75   // Compare signs.
76   int neg = x->type & V_ASN1_NEG;
77   if (neg != (y->type & V_ASN1_NEG)) {
78     return neg ? -1 : 1;
79   }
80 
81   int ret = ASN1_STRING_cmp(x, y);
82   if (neg) {
83     // This could be |-ret|, but |ASN1_STRING_cmp| is not forbidden from
84     // returning |INT_MIN|.
85     if (ret < 0) {
86       return 1;
87     } else if (ret > 0) {
88       return -1;
89     } else {
90       return 0;
91     }
92   }
93 
94   return ret;
95 }
96 
97 // negate_twos_complement negates |len| bytes from |buf| in-place, interpreted
98 // as a signed, big-endian two's complement value.
negate_twos_complement(uint8_t * buf,size_t len)99 static void negate_twos_complement(uint8_t *buf, size_t len) {
100   uint8_t borrow = 0;
101   for (size_t i = len - 1; i < len; i--) {
102     uint8_t t = buf[i];
103     buf[i] = 0u - borrow - t;
104     borrow |= t != 0;
105   }
106 }
107 
is_all_zeros(const uint8_t * in,size_t len)108 static int is_all_zeros(const uint8_t *in, size_t len) {
109   for (size_t i = 0; i < len; i++) {
110     if (in[i] != 0) {
111       return 0;
112     }
113   }
114   return 1;
115 }
116 
i2c_ASN1_INTEGER(const ASN1_INTEGER * in,unsigned char ** outp)117 int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) {
118   if (in == NULL) {
119     return 0;
120   }
121 
122   // |ASN1_INTEGER|s should be represented minimally, but it is possible to
123   // construct invalid ones. Skip leading zeros so this does not produce an
124   // invalid encoding or break invariants.
125   CBS cbs;
126   CBS_init(&cbs, in->data, in->length);
127   while (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0) {
128     CBS_skip(&cbs, 1);
129   }
130 
131   int is_negative = (in->type & V_ASN1_NEG) != 0;
132   size_t pad;
133   CBS copy = cbs;
134   uint8_t msb;
135   if (!CBS_get_u8(&copy, &msb)) {
136     // Zero is represented as a single byte.
137     is_negative = 0;
138     pad = 1;
139   } else if (is_negative) {
140     // 0x80...01 through 0xff...ff have a two's complement of 0x7f...ff
141     // through 0x00...01 and need an extra byte to be negative.
142     // 0x01...00 through 0x80...00 have a two's complement of 0xfe...ff
143     // through 0x80...00 and can be negated as-is.
144     pad = msb > 0x80 ||
145           (msb == 0x80 && !is_all_zeros(CBS_data(&copy), CBS_len(&copy)));
146   } else {
147     // If the high bit is set, the signed representation needs an extra
148     // byte to be positive.
149     pad = (msb & 0x80) != 0;
150   }
151 
152   if (CBS_len(&cbs) > INT_MAX - pad) {
153     OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW);
154     return 0;
155   }
156   int len = (int)(pad + CBS_len(&cbs));
157   assert(len > 0);
158   if (outp == NULL) {
159     return len;
160   }
161 
162   if (pad) {
163     (*outp)[0] = 0;
164   }
165   OPENSSL_memcpy(*outp + pad, CBS_data(&cbs), CBS_len(&cbs));
166   if (is_negative) {
167     negate_twos_complement(*outp, len);
168     assert((*outp)[0] >= 0x80);
169   } else {
170     assert((*outp)[0] < 0x80);
171   }
172   *outp += len;
173   return len;
174 }
175 
c2i_ASN1_INTEGER(ASN1_INTEGER ** out,const unsigned char ** inp,long len)176 ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp,
177                                long len) {
178   // This function can handle lengths up to INT_MAX - 1, but the rest of the
179   // legacy ASN.1 code mixes integer types, so avoid exposing it to
180   // ASN1_INTEGERS with larger lengths.
181   if (len < 0 || len > INT_MAX / 2) {
182     OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
183     return NULL;
184   }
185 
186   CBS cbs;
187   CBS_init(&cbs, *inp, (size_t)len);
188   int is_negative;
189   if (!CBS_is_valid_asn1_integer(&cbs, &is_negative)) {
190     OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
191     return NULL;
192   }
193 
194   ASN1_INTEGER *ret = NULL;
195   if (out == NULL || *out == NULL) {
196     ret = ASN1_INTEGER_new();
197     if (ret == NULL) {
198       return NULL;
199     }
200   } else {
201     ret = *out;
202   }
203 
204   // Convert to |ASN1_INTEGER|'s sign-and-magnitude representation. First,
205   // determine the size needed for a minimal result.
206   if (is_negative) {
207     // 0xff00...01 through 0xff7f..ff have a two's complement of 0x00ff...ff
208     // through 0x000100...001 and need one leading zero removed. 0x8000...00
209     // through 0xff00...00 have a two's complement of 0x8000...00 through
210     // 0x0100...00 and will be minimally-encoded as-is.
211     if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0xff &&
212         !is_all_zeros(CBS_data(&cbs) + 1, CBS_len(&cbs) - 1)) {
213       CBS_skip(&cbs, 1);
214     }
215   } else {
216     // Remove the leading zero byte, if any.
217     if (CBS_len(&cbs) > 0 && CBS_data(&cbs)[0] == 0x00) {
218       CBS_skip(&cbs, 1);
219     }
220   }
221 
222   if (!ASN1_STRING_set(ret, CBS_data(&cbs), CBS_len(&cbs))) {
223     goto err;
224   }
225 
226   if (is_negative) {
227     ret->type = V_ASN1_NEG_INTEGER;
228     negate_twos_complement(ret->data, ret->length);
229   } else {
230     ret->type = V_ASN1_INTEGER;
231   }
232 
233   // The value should be minimally-encoded.
234   assert(ret->length == 0 || ret->data[0] != 0);
235   // Zero is not negative.
236   assert(!is_negative || ret->length > 0);
237 
238   *inp += len;
239   if (out != NULL) {
240     *out = ret;
241   }
242   return ret;
243 
244 err:
245   if (ret != NULL && (out == NULL || *out != ret)) {
246     ASN1_INTEGER_free(ret);
247   }
248   return NULL;
249 }
250 
ASN1_INTEGER_set_int64(ASN1_INTEGER * a,int64_t v)251 int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t v) {
252   if (v >= 0) {
253     return ASN1_INTEGER_set_uint64(a, (uint64_t)v);
254   }
255 
256   if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t)v)) {
257     return 0;
258   }
259 
260   a->type = V_ASN1_NEG_INTEGER;
261   return 1;
262 }
263 
ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED * a,int64_t v)264 int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t v) {
265   if (v >= 0) {
266     return ASN1_ENUMERATED_set_uint64(a, (uint64_t)v);
267   }
268 
269   if (!ASN1_ENUMERATED_set_uint64(a, 0 - (uint64_t)v)) {
270     return 0;
271   }
272 
273   a->type = V_ASN1_NEG_ENUMERATED;
274   return 1;
275 }
276 
ASN1_INTEGER_set(ASN1_INTEGER * a,long v)277 int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) {
278   static_assert(sizeof(long) <= sizeof(int64_t), "long fits in int64_t");
279   return ASN1_INTEGER_set_int64(a, v);
280 }
281 
ASN1_ENUMERATED_set(ASN1_ENUMERATED * a,long v)282 int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) {
283   static_assert(sizeof(long) <= sizeof(int64_t), "long fits in int64_t");
284   return ASN1_ENUMERATED_set_int64(a, v);
285 }
286 
asn1_string_set_uint64(ASN1_STRING * out,uint64_t v,int type)287 static int asn1_string_set_uint64(ASN1_STRING *out, uint64_t v, int type) {
288   uint8_t buf[sizeof(uint64_t)];
289   CRYPTO_store_u64_be(buf, v);
290   size_t leading_zeros;
291   for (leading_zeros = 0; leading_zeros < sizeof(buf); leading_zeros++) {
292     if (buf[leading_zeros] != 0) {
293       break;
294     }
295   }
296 
297   if (!ASN1_STRING_set(out, buf + leading_zeros, sizeof(buf) - leading_zeros)) {
298     return 0;
299   }
300   out->type = type;
301   return 1;
302 }
303 
ASN1_INTEGER_set_uint64(ASN1_INTEGER * out,uint64_t v)304 int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v) {
305   return asn1_string_set_uint64(out, v, V_ASN1_INTEGER);
306 }
307 
ASN1_ENUMERATED_set_uint64(ASN1_ENUMERATED * out,uint64_t v)308 int ASN1_ENUMERATED_set_uint64(ASN1_ENUMERATED *out, uint64_t v) {
309   return asn1_string_set_uint64(out, v, V_ASN1_ENUMERATED);
310 }
311 
asn1_string_get_abs_uint64(uint64_t * out,const ASN1_STRING * a,int type)312 static int asn1_string_get_abs_uint64(uint64_t *out, const ASN1_STRING *a,
313                                       int type) {
314   if ((a->type & ~V_ASN1_NEG) != type) {
315     OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE);
316     return 0;
317   }
318   uint8_t buf[sizeof(uint64_t)] = {0};
319   if (a->length > (int)sizeof(buf)) {
320     OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
321     return 0;
322   }
323   OPENSSL_memcpy(buf + sizeof(buf) - a->length, a->data, a->length);
324   *out = CRYPTO_load_u64_be(buf);
325   return 1;
326 }
327 
asn1_string_get_uint64(uint64_t * out,const ASN1_STRING * a,int type)328 static int asn1_string_get_uint64(uint64_t *out, const ASN1_STRING *a,
329                                   int type) {
330   if (!asn1_string_get_abs_uint64(out, a, type)) {
331     return 0;
332   }
333   if (a->type & V_ASN1_NEG) {
334     OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
335     return 0;
336   }
337   return 1;
338 }
339 
ASN1_INTEGER_get_uint64(uint64_t * out,const ASN1_INTEGER * a)340 int ASN1_INTEGER_get_uint64(uint64_t *out, const ASN1_INTEGER *a) {
341   return asn1_string_get_uint64(out, a, V_ASN1_INTEGER);
342 }
343 
ASN1_ENUMERATED_get_uint64(uint64_t * out,const ASN1_ENUMERATED * a)344 int ASN1_ENUMERATED_get_uint64(uint64_t *out, const ASN1_ENUMERATED *a) {
345   return asn1_string_get_uint64(out, a, V_ASN1_ENUMERATED);
346 }
347 
asn1_string_get_int64(int64_t * out,const ASN1_STRING * a,int type)348 static int asn1_string_get_int64(int64_t *out, const ASN1_STRING *a, int type) {
349   uint64_t v;
350   if (!asn1_string_get_abs_uint64(&v, a, type)) {
351     return 0;
352   }
353   int64_t i64;
354   int fits_in_i64;
355   // Check |v != 0| to handle manually-constructed negative zeros.
356   if ((a->type & V_ASN1_NEG) && v != 0) {
357     i64 = (int64_t)(0u - v);
358     fits_in_i64 = i64 < 0;
359   } else {
360     i64 = (int64_t)v;
361     fits_in_i64 = i64 >= 0;
362   }
363   if (!fits_in_i64) {
364     OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER);
365     return 0;
366   }
367   *out = i64;
368   return 1;
369 }
370 
ASN1_INTEGER_get_int64(int64_t * out,const ASN1_INTEGER * a)371 int ASN1_INTEGER_get_int64(int64_t *out, const ASN1_INTEGER *a) {
372   return asn1_string_get_int64(out, a, V_ASN1_INTEGER);
373 }
374 
ASN1_ENUMERATED_get_int64(int64_t * out,const ASN1_ENUMERATED * a)375 int ASN1_ENUMERATED_get_int64(int64_t *out, const ASN1_ENUMERATED *a) {
376   return asn1_string_get_int64(out, a, V_ASN1_ENUMERATED);
377 }
378 
asn1_string_get_long(const ASN1_STRING * a,int type)379 static long asn1_string_get_long(const ASN1_STRING *a, int type) {
380   if (a == NULL) {
381     return 0;
382   }
383 
384   int64_t v;
385   if (!asn1_string_get_int64(&v, a, type) ||  //
386       v < LONG_MIN || v > LONG_MAX) {
387     // This function's return value does not distinguish overflow from -1.
388     ERR_clear_error();
389     return -1;
390   }
391 
392   return (long)v;
393 }
394 
ASN1_INTEGER_get(const ASN1_INTEGER * a)395 long ASN1_INTEGER_get(const ASN1_INTEGER *a) {
396   return asn1_string_get_long(a, V_ASN1_INTEGER);
397 }
398 
ASN1_ENUMERATED_get(const ASN1_ENUMERATED * a)399 long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a) {
400   return asn1_string_get_long(a, V_ASN1_ENUMERATED);
401 }
402 
bn_to_asn1_string(const BIGNUM * bn,ASN1_STRING * ai,int type)403 static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai,
404                                       int type) {
405   ASN1_INTEGER *ret;
406   if (ai == NULL) {
407     ret = ASN1_STRING_type_new(type);
408   } else {
409     ret = ai;
410   }
411   if (ret == NULL) {
412     OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
413     goto err;
414   }
415 
416   if (BN_is_negative(bn) && !BN_is_zero(bn)) {
417     ret->type = type | V_ASN1_NEG;
418   } else {
419     ret->type = type;
420   }
421 
422   int len = BN_num_bytes(bn);
423   if (!ASN1_STRING_set(ret, NULL, len) ||
424       !BN_bn2bin_padded(ret->data, len, bn)) {
425     goto err;
426   }
427   return ret;
428 
429 err:
430   if (ret != ai) {
431     ASN1_STRING_free(ret);
432   }
433   return NULL;
434 }
435 
BN_to_ASN1_INTEGER(const BIGNUM * bn,ASN1_INTEGER * ai)436 ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) {
437   return bn_to_asn1_string(bn, ai, V_ASN1_INTEGER);
438 }
439 
BN_to_ASN1_ENUMERATED(const BIGNUM * bn,ASN1_ENUMERATED * ai)440 ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai) {
441   return bn_to_asn1_string(bn, ai, V_ASN1_ENUMERATED);
442 }
443 
asn1_string_to_bn(const ASN1_STRING * ai,BIGNUM * bn,int type)444 static BIGNUM *asn1_string_to_bn(const ASN1_STRING *ai, BIGNUM *bn, int type) {
445   if ((ai->type & ~V_ASN1_NEG) != type) {
446     OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_INTEGER_TYPE);
447     return NULL;
448   }
449 
450   BIGNUM *ret;
451   if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) {
452     OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
453   } else if (ai->type & V_ASN1_NEG) {
454     BN_set_negative(ret, 1);
455   }
456   return ret;
457 }
458 
ASN1_INTEGER_to_BN(const ASN1_INTEGER * ai,BIGNUM * bn)459 BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) {
460   return asn1_string_to_bn(ai, bn, V_ASN1_INTEGER);
461 }
462 
ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED * ai,BIGNUM * bn)463 BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn) {
464   return asn1_string_to_bn(ai, bn, V_ASN1_ENUMERATED);
465 }
466