summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2023-04-19 11:12:43 +0000
committerjsing <>2023-04-19 11:12:43 +0000
commit5a95f15643e5a185fdbb26cc7ba82e4d4cd81a2c (patch)
tree2461d4cee6baae82d4b72682debb72926862a492 /src/lib
parentfc88bfb589877f9d7cbcaa0bdc9fad3d86931d13 (diff)
downloadopenbsd-5a95f15643e5a185fdbb26cc7ba82e4d4cd81a2c.tar.gz
openbsd-5a95f15643e5a185fdbb26cc7ba82e4d4cd81a2c.tar.bz2
openbsd-5a95f15643e5a185fdbb26cc7ba82e4d4cd81a2c.zip
Move the BN_bn2bin()/BN_bin2bn() family to bn_convert.c
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/bn/bn_convert.c183
-rw-r--r--src/lib/libcrypto/bn/bn_lib.c182
2 files changed, 183 insertions, 182 deletions
diff --git a/src/lib/libcrypto/bn/bn_convert.c b/src/lib/libcrypto/bn/bn_convert.c
index 6fe30fdbb9..5df79fded6 100644
--- a/src/lib/libcrypto/bn/bn_convert.c
+++ b/src/lib/libcrypto/bn/bn_convert.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_convert.c,v 1.4 2023/04/19 11:05:11 jsing Exp $ */ 1/* $OpenBSD: bn_convert.c,v 1.5 2023/04/19 11:12:43 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -59,6 +59,7 @@
59#include <ctype.h> 59#include <ctype.h>
60#include <limits.h> 60#include <limits.h>
61#include <stdio.h> 61#include <stdio.h>
62#include <string.h>
62 63
63#include <openssl/opensslconf.h> 64#include <openssl/opensslconf.h>
64 65
@@ -70,6 +71,186 @@
70 71
71static const char Hex[]="0123456789ABCDEF"; 72static const char Hex[]="0123456789ABCDEF";
72 73
74typedef enum {
75 big,
76 little,
77} endianness_t;
78
79/* ignore negative */
80static int
81bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianness_t endianness)
82{
83 int n;
84 size_t i, lasti, j, atop, mask;
85 BN_ULONG l;
86
87 /*
88 * In case |a| is fixed-top, BN_num_bytes can return bogus length,
89 * but it's assumed that fixed-top inputs ought to be "nominated"
90 * even for padded output, so it works out...
91 */
92 n = BN_num_bytes(a);
93 if (tolen == -1)
94 tolen = n;
95 else if (tolen < n) { /* uncommon/unlike case */
96 BIGNUM temp = *a;
97
98 bn_correct_top(&temp);
99
100 n = BN_num_bytes(&temp);
101 if (tolen < n)
102 return -1;
103 }
104
105 /* Swipe through whole available data and don't give away padded zero. */
106 atop = a->dmax * BN_BYTES;
107 if (atop == 0) {
108 explicit_bzero(to, tolen);
109 return tolen;
110 }
111
112 lasti = atop - 1;
113 atop = a->top * BN_BYTES;
114
115 if (endianness == big)
116 to += tolen; /* start from the end of the buffer */
117
118 for (i = 0, j = 0; j < (size_t)tolen; j++) {
119 unsigned char val;
120
121 l = a->d[i / BN_BYTES];
122 mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
123 val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
124
125 if (endianness == big)
126 *--to = val;
127 else
128 *to++ = val;
129
130 i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
131 }
132
133 return tolen;
134}
135
136int
137BN_bn2bin(const BIGNUM *a, unsigned char *to)
138{
139 return bn2binpad(a, to, -1, big);
140}
141
142int
143BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
144{
145 if (tolen < 0)
146 return -1;
147 return bn2binpad(a, to, tolen, big);
148}
149
150BIGNUM *
151BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
152{
153 unsigned int i, m;
154 unsigned int n;
155 BN_ULONG l;
156 BIGNUM *bn = NULL;
157
158 if (len < 0)
159 return (NULL);
160 if (ret == NULL)
161 ret = bn = BN_new();
162 if (ret == NULL)
163 return (NULL);
164 l = 0;
165 n = len;
166 if (n == 0) {
167 ret->top = 0;
168 return (ret);
169 }
170 i = ((n - 1) / BN_BYTES) + 1;
171 m = ((n - 1) % (BN_BYTES));
172 if (!bn_wexpand(ret, (int)i)) {
173 BN_free(bn);
174 return NULL;
175 }
176 ret->top = i;
177 ret->neg = 0;
178 while (n--) {
179 l = (l << 8L) | *(s++);
180 if (m-- == 0) {
181 ret->d[--i] = l;
182 l = 0;
183 m = BN_BYTES - 1;
184 }
185 }
186 /* need to call this due to clear byte at top if avoiding
187 * having the top bit set (-ve number) */
188 bn_correct_top(ret);
189 return (ret);
190}
191
192int
193BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
194{
195 if (tolen < 0)
196 return -1;
197
198 return bn2binpad(a, to, tolen, little);
199}
200
201BIGNUM *
202BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
203{
204 unsigned int i, m, n;
205 BN_ULONG l;
206 BIGNUM *bn = NULL;
207
208 if (ret == NULL)
209 ret = bn = BN_new();
210 if (ret == NULL)
211 return NULL;
212
213
214 s += len;
215 /* Skip trailing zeroes. */
216 for (; len > 0 && s[-1] == 0; s--, len--)
217 continue;
218
219 n = len;
220 if (n == 0) {
221 ret->top = 0;
222 return ret;
223 }
224
225 i = ((n - 1) / BN_BYTES) + 1;
226 m = (n - 1) % BN_BYTES;
227 if (!bn_wexpand(ret, (int)i)) {
228 BN_free(bn);
229 return NULL;
230 }
231
232 ret->top = i;
233 ret->neg = 0;
234 l = 0;
235 while (n-- > 0) {
236 s--;
237 l = (l << 8L) | *s;
238 if (m-- == 0) {
239 ret->d[--i] = l;
240 l = 0;
241 m = BN_BYTES - 1;
242 }
243 }
244
245 /*
246 * need to call this due to clear byte at top if avoiding having the
247 * top bit set (-ve number)
248 */
249 bn_correct_top(ret);
250
251 return ret;
252}
253
73int 254int
74BN_asc2bn(BIGNUM **bn, const char *a) 255BN_asc2bn(BIGNUM **bn, const char *a)
75{ 256{
diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c
index cd06563a5d..78410e2133 100644
--- a/src/lib/libcrypto/bn/bn_lib.c
+++ b/src/lib/libcrypto/bn/bn_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_lib.c,v 1.83 2023/04/19 10:54:49 jsing Exp $ */ 1/* $OpenBSD: bn_lib.c,v 1.84 2023/04/19 11:12:43 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -435,186 +435,6 @@ BN_set_word(BIGNUM *a, BN_ULONG w)
435 return (1); 435 return (1);
436} 436}
437 437
438BIGNUM *
439BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
440{
441 unsigned int i, m;
442 unsigned int n;
443 BN_ULONG l;
444 BIGNUM *bn = NULL;
445
446 if (len < 0)
447 return (NULL);
448 if (ret == NULL)
449 ret = bn = BN_new();
450 if (ret == NULL)
451 return (NULL);
452 l = 0;
453 n = len;
454 if (n == 0) {
455 ret->top = 0;
456 return (ret);
457 }
458 i = ((n - 1) / BN_BYTES) + 1;
459 m = ((n - 1) % (BN_BYTES));
460 if (!bn_wexpand(ret, (int)i)) {
461 BN_free(bn);
462 return NULL;
463 }
464 ret->top = i;
465 ret->neg = 0;
466 while (n--) {
467 l = (l << 8L) | *(s++);
468 if (m-- == 0) {
469 ret->d[--i] = l;
470 l = 0;
471 m = BN_BYTES - 1;
472 }
473 }
474 /* need to call this due to clear byte at top if avoiding
475 * having the top bit set (-ve number) */
476 bn_correct_top(ret);
477 return (ret);
478}
479
480typedef enum {
481 big,
482 little,
483} endianness_t;
484
485/* ignore negative */
486static int
487bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianness_t endianness)
488{
489 int n;
490 size_t i, lasti, j, atop, mask;
491 BN_ULONG l;
492
493 /*
494 * In case |a| is fixed-top, BN_num_bytes can return bogus length,
495 * but it's assumed that fixed-top inputs ought to be "nominated"
496 * even for padded output, so it works out...
497 */
498 n = BN_num_bytes(a);
499 if (tolen == -1)
500 tolen = n;
501 else if (tolen < n) { /* uncommon/unlike case */
502 BIGNUM temp = *a;
503
504 bn_correct_top(&temp);
505
506 n = BN_num_bytes(&temp);
507 if (tolen < n)
508 return -1;
509 }
510
511 /* Swipe through whole available data and don't give away padded zero. */
512 atop = a->dmax * BN_BYTES;
513 if (atop == 0) {
514 explicit_bzero(to, tolen);
515 return tolen;
516 }
517
518 lasti = atop - 1;
519 atop = a->top * BN_BYTES;
520
521 if (endianness == big)
522 to += tolen; /* start from the end of the buffer */
523
524 for (i = 0, j = 0; j < (size_t)tolen; j++) {
525 unsigned char val;
526
527 l = a->d[i / BN_BYTES];
528 mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
529 val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
530
531 if (endianness == big)
532 *--to = val;
533 else
534 *to++ = val;
535
536 i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
537 }
538
539 return tolen;
540}
541
542int
543BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
544{
545 if (tolen < 0)
546 return -1;
547 return bn2binpad(a, to, tolen, big);
548}
549
550int
551BN_bn2bin(const BIGNUM *a, unsigned char *to)
552{
553 return bn2binpad(a, to, -1, big);
554}
555
556BIGNUM *
557BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
558{
559 unsigned int i, m, n;
560 BN_ULONG l;
561 BIGNUM *bn = NULL;
562
563 if (ret == NULL)
564 ret = bn = BN_new();
565 if (ret == NULL)
566 return NULL;
567
568
569 s += len;
570 /* Skip trailing zeroes. */
571 for (; len > 0 && s[-1] == 0; s--, len--)
572 continue;
573
574 n = len;
575 if (n == 0) {
576 ret->top = 0;
577 return ret;
578 }
579
580 i = ((n - 1) / BN_BYTES) + 1;
581 m = (n - 1) % BN_BYTES;
582 if (!bn_wexpand(ret, (int)i)) {
583 BN_free(bn);
584 return NULL;
585 }
586
587 ret->top = i;
588 ret->neg = 0;
589 l = 0;
590 while (n-- > 0) {
591 s--;
592 l = (l << 8L) | *s;
593 if (m-- == 0) {
594 ret->d[--i] = l;
595 l = 0;
596 m = BN_BYTES - 1;
597 }
598 }
599
600 /*
601 * need to call this due to clear byte at top if avoiding having the
602 * top bit set (-ve number)
603 */
604 bn_correct_top(ret);
605
606 return ret;
607}
608
609int
610BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
611{
612 if (tolen < 0)
613 return -1;
614
615 return bn2binpad(a, to, tolen, little);
616}
617
618int 438int
619BN_ucmp(const BIGNUM *a, const BIGNUM *b) 439BN_ucmp(const BIGNUM *a, const BIGNUM *b)
620{ 440{