diff options
Diffstat (limited to 'security/libnetpgpverify/files/src')
32 files changed, 0 insertions, 13082 deletions
diff --git a/security/libnetpgpverify/files/src/libbn/Makefile b/security/libnetpgpverify/files/src/libbn/Makefile deleted file mode 100644 index 4c7c15c274c..00000000000 --- a/security/libnetpgpverify/files/src/libbn/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -LIB=netbn -SRCS= bignum.c digest.c misc.c rand.c -SRCS+= stubs.c -MKMAN=no -WARNS=4 -CPPFLAGS+=-I${EXTDIST} - -INCS=bn.h digest.h -INCSDIR=/usr/include/netpgp - -EXTDIST= ${.CURDIR}/../cipher - -.include <bsd.lib.mk> diff --git a/security/libnetpgpverify/files/src/libbn/bignum.c b/security/libnetpgpverify/files/src/libbn/bignum.c deleted file mode 100644 index 2002c78c1a4..00000000000 --- a/security/libnetpgpverify/files/src/libbn/bignum.c +++ /dev/null @@ -1,5637 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> - -#ifdef _KERNEL -# include <sys/kmem.h> -#else -# include <arpa/inet.h> -# include <ctype.h> -# include <inttypes.h> -# include <stdarg.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# include <time.h> -# include <unistd.h> -#endif - -#include "misc.h" -#include "bn.h" -#include "digest.h" - -/**************************************************************************/ - -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -#define MP_PREC 32 -#define DIGIT_BIT 28 -#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) - -#define MP_WARRAY /*LINTED*/(1U << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT) + 1))) - -#define MP_NO 0 -#define MP_YES 1 - -#ifndef USE_ARG -#define USE_ARG(x) /*LINTED*/(void)&(x) -#endif - -#ifndef __arraycount -#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0])) -#endif - -#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) - -#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) - -typedef int mp_err; - -static int mp_mul(mp_int * a, mp_int * b, mp_int * c); -static int mp_sqr(mp_int * a, mp_int * b); - -static int mp_sub_d(mp_int *a, mp_digit b, mp_int *c); - -/* set to zero */ -static void -mp_zero(mp_int *a) -{ - int n; - mp_digit *tmp; - - a->sign = MP_ZPOS; - a->used = 0; - - tmp = a->dp; - /* XXX - memset */ - for (n = 0; n < a->alloc; n++) { - *tmp++ = 0; - } -} - -/* grow as required */ -static int -mp_grow(mp_int *a, int size) -{ - int i; - mp_digit *tmp; - - /* if the alloc size is smaller alloc more ram */ - if (a->alloc < size) { - /* ensure there are always at least MP_PREC digits extra on top */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* reallocate the array a->dp - * - * We store the return in a temporary variable - * in case the operation failed we don't want - * to overwrite the dp member of a. - */ - tmp = realloc(a->dp, sizeof(*tmp) * size); - if (tmp == NULL) { - /* reallocation failed but "a" is still valid [can be freed] */ - return MP_MEM; - } - - /* reallocation succeeded so set a->dp */ - a->dp = tmp; - - /* zero excess digits */ - i = a->alloc; - a->alloc = size; - for (; i < a->alloc; i++) { - a->dp[i] = 0; - } - } - return MP_OKAY; -} - -/* shift left a certain amount of digits */ -static int -mp_lshd (mp_int * a, int b) -{ - int x, res; - - /* if its less than zero return */ - if (b <= 0) { - return MP_OKAY; - } - - /* grow to fit the new digits */ - if (a->alloc < a->used + b) { - if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { - return res; - } - } - - { - mp_digit *top, *bottom; - - /* increment the used by the shift amount then copy upwards */ - a->used += b; - - /* top */ - top = a->dp + a->used - 1; - - /* base */ - bottom = a->dp + a->used - 1 - b; - - /* much like mp_rshd this is implemented using a sliding window - * except the window goes the otherway around. Copying from - * the bottom to the top. see bn_mp_rshd.c for more info. - */ - for (x = a->used - 1; x >= b; x--) { - *top-- = *bottom--; - } - - /* zero the lower digits */ - top = a->dp; - for (x = 0; x < b; x++) { - *top++ = 0; - } - } - return MP_OKAY; -} - -/* trim unused digits - * - * This is used to ensure that leading zero digits are - * trimed and the leading "used" digit will be non-zero - * Typically very fast. Also fixes the sign if there - * are no more leading digits - */ -static void -mp_clamp (mp_int * a) -{ - /* decrease used while the most significant digit is - * zero. - */ - while (a->used > 0 && a->dp[a->used - 1] == 0) { - --(a->used); - } - - /* reset the sign flag if used == 0 */ - if (a->used == 0) { - a->sign = MP_ZPOS; - } -} - -/* copy, b = a */ -static int -mp_copy(BIGNUM *a, BIGNUM *b) -{ - int res, n; - - /* if dst == src do nothing */ - if (a == b) { - return MP_OKAY; - } - if (a == NULL || b == NULL) { - return MP_VAL; - } - - /* grow dest */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - /* zero b and copy the parameters over */ - { - mp_digit *tmpa, *tmpb; - - /* pointer aliases */ - - /* source */ - tmpa = a->dp; - - /* destination */ - tmpb = b->dp; - - /* copy all the digits */ - for (n = 0; n < a->used; n++) { - *tmpb++ = *tmpa++; - } - - /* clear high digits */ - for (; n < b->used; n++) { - *tmpb++ = 0; - } - } - - /* copy used count and sign */ - b->used = a->used; - b->sign = a->sign; - return MP_OKAY; -} - -/* shift left by a certain bit count */ -static int -mp_mul_2d(mp_int *a, int b, mp_int *c) -{ - mp_digit d; - int res; - - /* copy */ - if (a != c) { - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - } - - if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { - if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { - return res; - } - } - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { - return res; - } - } - - /* shift any bit count < DIGIT_BIT */ - d = (mp_digit) (b % DIGIT_BIT); - if (d != 0) { - mp_digit *tmpc, shift, mask, r, rr; - int x; - - /* bitmask for carries */ - mask = (((mp_digit)1) << d) - 1; - - /* shift for msbs */ - shift = DIGIT_BIT - d; - - /* alias */ - tmpc = c->dp; - - /* carry */ - r = 0; - for (x = 0; x < c->used; x++) { - /* get the higher bits of the current word */ - rr = (*tmpc >> shift) & mask; - - /* shift the current word and OR in the carry */ - *tmpc = ((*tmpc << d) | r) & MP_MASK; - ++tmpc; - - /* set the carry to the carry bits of the current word */ - r = rr; - } - - /* set final carry */ - if (r != 0) { - c->dp[(c->used)++] = r; - } - } - mp_clamp (c); - return MP_OKAY; -} - -/* reads a unsigned char array, assumes the msb is stored first [big endian] */ -static int -mp_read_unsigned_bin(mp_int *a, const uint8_t *b, int c) -{ - int res; - - /* make sure there are at least two digits */ - if (a->alloc < 2) { - if ((res = mp_grow(a, 2)) != MP_OKAY) { - return res; - } - } - - /* zero the int */ - mp_zero (a); - - /* read the bytes in */ - while (c-- > 0) { - if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { - return res; - } - - a->dp[0] |= *b++; - a->used += 1; - } - mp_clamp (a); - return MP_OKAY; -} - -/* returns the number of bits in an int */ -static int -mp_count_bits(const mp_int *a) -{ - int r; - mp_digit q; - - /* shortcut */ - if (a->used == 0) { - return 0; - } - - /* get number of digits and add that */ - r = (a->used - 1) * DIGIT_BIT; - - /* take the last digit and count the bits in it */ - q = a->dp[a->used - 1]; - while (q > ((mp_digit) 0)) { - ++r; - q >>= ((mp_digit) 1); - } - return r; -} - -/* compare maginitude of two ints (unsigned) */ -static int -mp_cmp_mag (mp_int * a, mp_int * b) -{ - int n; - mp_digit *tmpa, *tmpb; - - /* compare based on # of non-zero digits */ - if (a->used > b->used) { - return MP_GT; - } - - if (a->used < b->used) { - return MP_LT; - } - - /* alias for a */ - tmpa = a->dp + (a->used - 1); - - /* alias for b */ - tmpb = b->dp + (a->used - 1); - - /* compare based on digits */ - for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { - if (*tmpa > *tmpb) { - return MP_GT; - } - - if (*tmpa < *tmpb) { - return MP_LT; - } - } - return MP_EQ; -} - -/* compare two ints (signed)*/ -static int -mp_cmp (mp_int * a, mp_int * b) -{ - /* compare based on sign */ - if (a->sign != b->sign) { - if (a->sign == MP_NEG) { - return MP_LT; - } else { - return MP_GT; - } - } - - /* compare digits */ - if (a->sign == MP_NEG) { - /* if negative compare opposite direction */ - return mp_cmp_mag(b, a); - } else { - return mp_cmp_mag(a, b); - } -} - -/* get the size for an unsigned equivalent */ -static int -mp_unsigned_bin_size (mp_int * a) -{ - int size = mp_count_bits (a); - return (size / 8 + ((size & 7) != 0 ? 1 : 0)); -} - -/* init a new mp_int */ -static int -mp_init (mp_int * a) -{ - int i; - - /* allocate memory required and clear it */ - a->dp = netpgp_allocate(1, sizeof (*a->dp) * MP_PREC); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the digits to zero */ - for (i = 0; i < MP_PREC; i++) { - a->dp[i] = 0; - } - - /* set the used to zero, allocated digits to the default precision - * and sign to positive */ - a->used = 0; - a->alloc = MP_PREC; - a->sign = MP_ZPOS; - - return MP_OKAY; -} - -/* clear one (frees) */ -static void -mp_clear (mp_int * a) -{ - int i; - - /* only do anything if a hasn't been freed previously */ - if (a->dp != NULL) { - /* first zero the digits */ - for (i = 0; i < a->used; i++) { - a->dp[i] = 0; - } - - /* free ram */ - netpgp_deallocate(a->dp, (size_t)a->alloc); - - /* reset members to make debugging easier */ - a->dp = NULL; - a->alloc = a->used = 0; - a->sign = MP_ZPOS; - } -} - -static int -mp_init_multi(mp_int *mp, ...) -{ - mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ - int n = 0; /* Number of ok inits */ - mp_int* cur_arg = mp; - va_list args; - - va_start(args, mp); /* init args to next argument from caller */ - while (cur_arg != NULL) { - if (mp_init(cur_arg) != MP_OKAY) { - /* Oops - error! Back-track and mp_clear what we already - succeeded in init-ing, then return error. - */ - va_list clean_args; - - /* end the current list */ - va_end(args); - - /* now start cleaning up */ - cur_arg = mp; - va_start(clean_args, mp); - while (n--) { - mp_clear(cur_arg); - cur_arg = va_arg(clean_args, mp_int*); - } - va_end(clean_args); - res = MP_MEM; - break; - } - n++; - cur_arg = va_arg(args, mp_int*); - } - va_end(args); - return res; /* Assumed ok, if error flagged above. */ -} - -/* init an mp_init for a given size */ -static int -mp_init_size (mp_int * a, int size) -{ - int x; - - /* pad size so there are always extra digits */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* alloc mem */ - a->dp = netpgp_allocate (1, sizeof (*a->dp) * size); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the members */ - a->used = 0; - a->alloc = size; - a->sign = MP_ZPOS; - - /* zero the digits */ - for (x = 0; x < size; x++) { - a->dp[x] = 0; - } - - return MP_OKAY; -} - -/* creates "a" then copies b into it */ -static int mp_init_copy (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_init (a)) != MP_OKAY) { - return res; - } - return mp_copy (b, a); -} - -/* low level addition, based on HAC pp.594, Algorithm 14.7 */ -static int -s_mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int *x; - int olduse, res, min, max; - - /* find sizes, we let |a| <= |b| which means we have to sort - * them. "x" will point to the input with the most digits - */ - if (a->used > b->used) { - min = b->used; - max = a->used; - x = a; - } else { - min = a->used; - max = b->used; - x = b; - } - - /* init result */ - if (c->alloc < max + 1) { - if ((res = mp_grow (c, max + 1)) != MP_OKAY) { - return res; - } - } - - /* get old used digit count and set new one */ - olduse = c->used; - c->used = max + 1; - - { - mp_digit u, *tmpa, *tmpb, *tmpc; - int i; - - /* alias for digit pointers */ - - /* first input */ - tmpa = a->dp; - - /* second input */ - tmpb = b->dp; - - /* destination */ - tmpc = c->dp; - - /* zero the carry */ - u = 0; - for (i = 0; i < min; i++) { - /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ - *tmpc = *tmpa++ + *tmpb++ + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, that is in A+B - * if A or B has more digits add those in - */ - if (min != max) { - for (; i < max; i++) { - /* T[i] = X[i] + U */ - *tmpc = x->dp[i] + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - } - - /* add carry */ - *tmpc++ = u; - - /* clear digits above oldused */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } - - mp_clamp (c); - return MP_OKAY; -} - -/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ -static int -s_mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - int olduse, res, min, max; - - /* find sizes */ - min = b->used; - max = a->used; - - /* init result */ - if (c->alloc < max) { - if ((res = mp_grow (c, max)) != MP_OKAY) { - return res; - } - } - olduse = c->used; - c->used = max; - - { - mp_digit u, *tmpa, *tmpb, *tmpc; - int i; - - /* alias for digit pointers */ - tmpa = a->dp; - tmpb = b->dp; - tmpc = c->dp; - - /* set carry to zero */ - u = 0; - for (i = 0; i < min; i++) { - /* T[i] = A[i] - B[i] - U */ - *tmpc = *tmpa++ - *tmpb++ - u; - - /* U = carry bit of T[i] - * Note this saves performing an AND operation since - * if a carry does occur it will propagate all the way to the - * MSB. As a result a single shift is enough to get the carry - */ - u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); - - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, e.g. if A has more digits than B */ - for (; i < max; i++) { - /* T[i] = A[i] - U */ - *tmpc = *tmpa++ - u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); - - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* clear digits above used (since we may not have grown result above) */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } - - mp_clamp (c); - return MP_OKAY; -} - -/* high level subtraction (handles signs) */ -static int -mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - int sa, sb, res; - - sa = a->sign; - sb = b->sign; - - if (sa != sb) { - /* subtract a negative from a positive, OR */ - /* subtract a positive from a negative. */ - /* In either case, ADD their magnitudes, */ - /* and use the sign of the first number. */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* subtract a positive from a positive, OR */ - /* subtract a negative from a negative. */ - /* First, take the difference between their */ - /* magnitudes, then... */ - if (mp_cmp_mag (a, b) != MP_LT) { - /* Copy the sign from the first */ - c->sign = sa; - /* The first has a larger or equal magnitude */ - res = s_mp_sub (a, b, c); - } else { - /* The result has the *opposite* sign from */ - /* the first number. */ - c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; - /* The second has a larger magnitude */ - res = s_mp_sub (b, a, c); - } - } - return res; -} - -/* shift right a certain amount of digits */ -static int mp_rshd (mp_int * a, int b) -{ - int x; - - /* if b <= 0 then ignore it */ - if (b <= 0) { - return 0; - } - - /* if b > used then simply zero it and return */ - if (a->used <= b) { - mp_zero (a); - return 0; - } - - { - mp_digit *bottom, *top; - - /* shift the digits down */ - - /* bottom */ - bottom = a->dp; - - /* top [offset into digits] */ - top = a->dp + b; - - /* this is implemented as a sliding window where - * the window is b-digits long and digits from - * the top of the window are copied to the bottom - * - * e.g. - - b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> - /\ | ----> - \-------------------/ ----> - */ - for (x = 0; x < (a->used - b); x++) { - *bottom++ = *top++; - } - - /* zero the top digits */ - for (; x < a->used; x++) { - *bottom++ = 0; - } - } - - /* remove excess digits */ - a->used -= b; - return 1; -} - -/* multiply by a digit */ -static int -mp_mul_d (mp_int * a, mp_digit b, mp_int * c) -{ - mp_digit u, *tmpa, *tmpc; - mp_word r; - int ix, res, olduse; - - /* make sure c is big enough to hold a*b */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* get the original destinations used count */ - olduse = c->used; - - /* set the sign */ - c->sign = a->sign; - - /* alias for a->dp [source] */ - tmpa = a->dp; - - /* alias for c->dp [dest] */ - tmpc = c->dp; - - /* zero carry */ - u = 0; - - /* compute columns */ - for (ix = 0; ix < a->used; ix++) { - /* compute product and carry sum for this term */ - r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); - - /* mask off higher bits to get a single digit */ - *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* send carry into next iteration */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - - /* store final carry [if any] and increment ix offset */ - *tmpc++ = u; - ++ix; - - /* now zero digits above the top */ - while (ix++ < olduse) { - *tmpc++ = 0; - } - - /* set used count */ - c->used = a->used + 1; - mp_clamp(c); - - return MP_OKAY; -} - -/* high level addition (handles signs) */ -static int mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - int sa, sb, res; - - /* get sign of both inputs */ - sa = a->sign; - sb = b->sign; - - /* handle two cases, not four */ - if (sa == sb) { - /* both positive or both negative */ - /* add their magnitudes, copy the sign */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* one positive, the other negative */ - /* subtract the one with the greater magnitude from */ - /* the one of the lesser magnitude. The result gets */ - /* the sign of the one with the greater magnitude. */ - if (mp_cmp_mag (a, b) == MP_LT) { - c->sign = sb; - res = s_mp_sub (b, a, c); - } else { - c->sign = sa; - res = s_mp_sub (a, b, c); - } - } - return res; -} - -/* swap the elements of two integers, for cases where you can't simply swap the - * mp_int pointers around - */ -static void -mp_exch(mp_int *a, mp_int *b) -{ - mp_int t; - - t = *a; - *a = *b; - *b = t; -} - -/* calc a value mod 2**b */ -static int -mp_mod_2d (mp_int * a, int b, mp_int * c) -{ - int x, res; - - /* if b is <= 0 then zero the int */ - if (b <= 0) { - mp_zero (c); - return MP_OKAY; - } - - /* if the modulus is larger than the value than return */ - if (b >= (int) (a->used * DIGIT_BIT)) { - res = mp_copy (a, c); - return res; - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - - /* zero digits above the last digit of the modulus */ - for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { - c->dp[x] = 0; - } - /* clear the digit that is not completely outside/inside the modulus */ - c->dp[b / DIGIT_BIT] &= - (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); - mp_clamp (c); - return MP_OKAY; -} - -/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ -static int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) -{ - mp_digit D, r, rr; - int x, res; - mp_int t; - - - /* if the shift count is <= 0 then we do no work */ - if (b <= 0) { - res = mp_copy (a, c); - if (d != NULL) { - mp_zero (d); - } - return res; - } - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - /* get the remainder */ - if (d != NULL) { - if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - mp_clear (&t); - return res; - } - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - mp_rshd (c, b / DIGIT_BIT); - } - - /* shift any bit count < DIGIT_BIT */ - D = (mp_digit) (b % DIGIT_BIT); - if (D != 0) { - mp_digit *tmpc, mask, shift; - - /* mask */ - mask = (((mp_digit)1) << D) - 1; - - /* shift for lsb */ - shift = DIGIT_BIT - D; - - /* alias */ - tmpc = c->dp + (c->used - 1); - - /* carry */ - r = 0; - for (x = c->used - 1; x >= 0; x--) { - /* get the lower bits of this word in a temp */ - rr = *tmpc & mask; - - /* shift the current word and mix in the carry bits from the previous word */ - *tmpc = (*tmpc >> D) | (r << shift); - --tmpc; - - /* set the carry to the carry bits of the current word found above */ - r = rr; - } - } - mp_clamp (c); - if (d != NULL) { - mp_exch (&t, d); - } - mp_clear (&t); - return MP_OKAY; -} - -/* integer signed division. - * c*b + d == a [e.g. a/b, c=quotient, d=remainder] - * HAC pp.598 Algorithm 14.20 - * - * Note that the description in HAC is horribly - * incomplete. For example, it doesn't consider - * the case where digits are removed from 'x' in - * the inner loop. It also doesn't consider the - * case that y has fewer than three digits, etc.. - * - * The overall algorithm is as described as - * 14.20 from HAC but fixed to treat these cases. -*/ -static int -mp_div(mp_int *c, mp_int *d, mp_int *a, mp_int *b) -{ - mp_int q, x, y, t1, t2; - int res, n, t, i, norm, neg; - - /* is divisor zero ? */ - if (BN_is_zero (b) == 1) { - return MP_VAL; - } - - /* if a < b then q=0, r = a */ - if (mp_cmp_mag (a, b) == MP_LT) { - if (d != NULL) { - res = mp_copy (a, d); - } else { - res = MP_OKAY; - } - if (c != NULL) { - mp_zero (c); - } - return res; - } - - if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { - return res; - } - q.used = a->used + 2; - - if ((res = mp_init (&t1)) != MP_OKAY) { - goto LBL_Q; - } - - if ((res = mp_init (&t2)) != MP_OKAY) { - goto LBL_T1; - } - - if ((res = mp_init_copy (&x, a)) != MP_OKAY) { - goto LBL_T2; - } - - if ((res = mp_init_copy (&y, b)) != MP_OKAY) { - goto LBL_X; - } - - /* fix the sign */ - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - x.sign = y.sign = MP_ZPOS; - - /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ - norm = mp_count_bits(&y) % DIGIT_BIT; - if (norm < (int)(DIGIT_BIT-1)) { - norm = (DIGIT_BIT-1) - norm; - if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { - goto LBL_Y; - } - } else { - norm = 0; - } - - /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ - n = x.used - 1; - t = y.used - 1; - - /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ - if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ - goto LBL_Y; - } - - while (mp_cmp (&x, &y) != MP_LT) { - ++(q.dp[n - t]); - if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { - goto LBL_Y; - } - } - - /* reset y by shifting it back down */ - mp_rshd (&y, n - t); - - /* step 3. for i from n down to (t + 1) */ - for (i = n; i >= (t + 1); i--) { - if (i > x.used) { - continue; - } - - /* step 3.1 if xi == yt then set q{i-t-1} to b-1, - * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ - if (x.dp[i] == y.dp[t]) { - q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); - } else { - mp_word tmp; - tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); - tmp |= ((mp_word) x.dp[i - 1]); - tmp /= ((mp_word) y.dp[t]); - if (tmp > (mp_word) MP_MASK) - tmp = MP_MASK; - q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); - } - - /* while (q{i-t-1} * (yt * b + y{t-1})) > - xi * b**2 + xi-1 * b + xi-2 - - do q{i-t-1} -= 1; - */ - q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK; - do { - q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK; - - /* find left hand */ - mp_zero (&t1); - t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; - t1.dp[1] = y.dp[t]; - t1.used = 2; - if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } - - /* find right hand */ - t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; - t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; - t2.dp[2] = x.dp[i]; - t2.used = 3; - } while (mp_cmp_mag(&t1, &t2) == MP_GT); - - /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ - if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } - - if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { - goto LBL_Y; - } - - if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } - - /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ - if (x.sign == MP_NEG) { - if ((res = mp_copy (&y, &t1)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } - - q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK; - } - } - - /* now q is the quotient and x is the remainder - * [which we have to normalize] - */ - - /* get sign before writing to c */ - x.sign = x.used == 0 ? MP_ZPOS : a->sign; - - if (c != NULL) { - mp_clamp (&q); - mp_exch (&q, c); - c->sign = neg; - } - - if (d != NULL) { - mp_div_2d (&x, norm, &x, NULL); - mp_exch (&x, d); - } - - res = MP_OKAY; - -LBL_Y:mp_clear (&y); -LBL_X:mp_clear (&x); -LBL_T2:mp_clear (&t2); -LBL_T1:mp_clear (&t1); -LBL_Q:mp_clear (&q); - return res; -} - -/* c = a mod b, 0 <= c < b */ -static int -mp_mod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int t; - int res; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_div (NULL, &t, a, b)) != MP_OKAY) { - mp_clear (&t); - return res; - } - - if (t.sign != b->sign) { - res = mp_add (b, &t, c); - } else { - res = MP_OKAY; - mp_exch (&t, c); - } - - mp_clear (&t); - return res; -} - -/* set to a digit */ -static void mp_set (mp_int * a, mp_digit b) -{ - mp_zero (a); - a->dp[0] = b & MP_MASK; - a->used = (a->dp[0] != 0) ? 1 : 0; -} - -/* b = a/2 */ -static int mp_div_2(mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* copy */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - { - mp_digit r, rr, *tmpa, *tmpb; - - /* source alias */ - tmpa = a->dp + b->used - 1; - - /* dest alias */ - tmpb = b->dp + b->used - 1; - - /* carry */ - r = 0; - for (x = b->used - 1; x >= 0; x--) { - /* get the carry for the next iteration */ - rr = *tmpa & 1; - - /* shift the current digit, add in carry and store */ - *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); - - /* forward carry to next iteration */ - r = rr; - } - - /* zero excess digits */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - mp_clamp (b); - return MP_OKAY; -} - -/* compare a digit */ -static int mp_cmp_d(mp_int * a, mp_digit b) -{ - /* compare based on sign */ - if (a->sign == MP_NEG) { - return MP_LT; - } - - /* compare based on magnitude */ - if (a->used > 1) { - return MP_GT; - } - - /* compare the only digit of a to b */ - if (a->dp[0] > b) { - return MP_GT; - } else if (a->dp[0] < b) { - return MP_LT; - } else { - return MP_EQ; - } -} - -static void mp_clear_multi(mp_int *mp, ...) -{ - mp_int* next_mp = mp; - va_list args; - va_start(args, mp); - while (next_mp != NULL) { - mp_clear(next_mp); - next_mp = va_arg(args, mp_int*); - } - va_end(args); -} - -/* computes the modular inverse via binary extended euclidean algorithm, - * that is c = 1/a mod b - * - * Based on slow invmod except this is optimized for the case where b is - * odd as per HAC Note 14.64 on pp. 610 - */ -static int -fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, B, D; - int res, neg; - - /* 2. [modified] b must be odd */ - if (BN_is_even (b) == 1) { - return MP_VAL; - } - - /* init all our temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { - return res; - } - - /* x == modulus, y == value to invert */ - if ((res = mp_copy (b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - - /* we need y = |a| */ - if ((res = mp_mod (a, b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (BN_is_even (&u) == 1) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if B is odd then */ - if (BN_is_odd (&B) == 1) { - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* B = B/2 */ - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (BN_is_even (&v) == 1) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if D is odd then */ - if (BN_is_odd (&D) == 1) { - /* D = (D-x)/2 */ - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* D = D/2 */ - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (BN_is_zero (&u) == 0) { - goto top; - } - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* b is now the inverse */ - neg = a->sign; - while (D.sign == MP_NEG) { - if ((res = mp_add (&D, b, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - mp_exch (&D, c); - c->sign = neg; - res = MP_OKAY; - -LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); - return res; -} - -/* hac 14.61, pp608 */ -static int -mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, A, B, C, D; - int res; - - /* b cannot be negative */ - if (b->sign == MP_NEG || BN_is_zero(b) == 1) { - return MP_VAL; - } - - /* init temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, - &A, &B, &C, &D, NULL)) != MP_OKAY) { - return res; - } - - /* x = a, y = b */ - if ((res = mp_mod(a, b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 2. [modified] if x,y are both even then return an error! */ - if (BN_is_even (&x) == 1 && BN_is_even (&y) == 1) { - res = MP_VAL; - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&A, 1); - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (BN_is_even (&u) == 1) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if A or B is odd then */ - if (BN_is_odd (&A) == 1 || BN_is_odd (&B) == 1) { - /* A = (A+y)/2, B = (B-x)/2 */ - if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* A = A/2, B = B/2 */ - if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (BN_is_even (&v) == 1) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if C or D is odd then */ - if (BN_is_odd (&C) == 1 || BN_is_odd (&D) == 1) { - /* C = (C+y)/2, D = (D-x)/2 */ - if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* C = C/2, D = D/2 */ - if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, A = A - C, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, C = C - A, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (BN_is_zero (&u) == 0) - goto top; - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* if its too low */ - while (mp_cmp_d(&C, 0) == MP_LT) { - if ((res = mp_add(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* too big */ - while (mp_cmp_mag(&C, b) != MP_LT) { - if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* C is now the inverse */ - mp_exch (&C, c); - res = MP_OKAY; -LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); - return res; -} - -static int -mp_invmod(mp_int *c, mp_int *a, mp_int *b) -{ - /* b cannot be negative */ - if (b->sign == MP_NEG || BN_is_zero(b) == 1) { - return MP_VAL; - } - - /* if the modulus is odd we can use a faster routine instead */ - if (BN_is_odd (b) == 1) { - return fast_mp_invmod(a, b, c); - } - - return mp_invmod_slow(a, b, c); - - /*NOTREACHED*/ - return MP_VAL; -} - -/* b = |a| - * - * Simple function copies the input and fixes the sign to positive - */ -static int -mp_abs (mp_int * a, mp_int * b) -{ - int res; - - /* copy a to b */ - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } - - /* force the sign of b to positive */ - b->sign = MP_ZPOS; - - return MP_OKAY; -} - -/* determines if reduce_2k_l can be used */ -static int mp_reduce_is_2k_l(mp_int *a) -{ - int ix, iy; - - if (a->used == 0) { - return MP_NO; - } else if (a->used == 1) { - return MP_YES; - } else if (a->used > 1) { - /* if more than half of the digits are -1 we're sold */ - for (iy = ix = 0; ix < a->used; ix++) { - if (a->dp[ix] == MP_MASK) { - ++iy; - } - } - return (iy >= (a->used/2)) ? MP_YES : MP_NO; - - } - return MP_NO; -} - -/* computes a = 2**b - * - * Simple algorithm which zeroes the int, grows it then just sets one bit - * as required. - */ -static int -mp_2expt (mp_int * a, int b) -{ - int res; - - /* zero a as per default */ - mp_zero (a); - - /* grow a to accomodate the single bit */ - if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { - return res; - } - - /* set the used count of where the bit will go */ - a->used = b / DIGIT_BIT + 1; - - /* put the single bit in its place */ - a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); - - return MP_OKAY; -} - -/* pre-calculate the value required for Barrett reduction - * For a given modulus "b" it calulates the value required in "a" - */ -static int mp_reduce_setup (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { - return res; - } - return mp_div (a, NULL, a, b); -} - -/* b = a*2 */ -static int mp_mul_2(mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* grow to accomodate result */ - if (b->alloc < a->used + 1) { - if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - - { - mp_digit r, rr, *tmpa, *tmpb; - - /* alias for source */ - tmpa = a->dp; - - /* alias for dest */ - tmpb = b->dp; - - /* carry */ - r = 0; - for (x = 0; x < a->used; x++) { - - /* get what will be the *next* carry bit from the - * MSB of the current digit - */ - rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); - - /* now shift up this digit, add in the carry [from the previous] */ - *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; - - /* copy the carry that would be from the source - * digit into the next iteration - */ - r = rr; - } - - /* new leading digit? */ - if (r != 0) { - /* add a MSB which is always 1 at this point */ - *tmpb = 1; - ++(b->used); - } - - /* now zero any excess digits on the destination - * that we didn't write to - */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - return MP_OKAY; -} - -/* divide by three (based on routine from MPI and the GMP manual) */ -static int -mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) -{ - mp_int q; - mp_word w, t; - mp_digit b; - int res, ix; - - /* b = 2**DIGIT_BIT / 3 */ - b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); - - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= 3) { - /* multiply w by [1/3] */ - t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); - - /* now subtract 3 * [w/3] from w, to get the remainder */ - w -= t+t+t; - - /* fixup the remainder as required since - * the optimization is not exact. - */ - while (w >= 3) { - t += 1; - w -= 3; - } - } else { - t = 0; - } - q.dp[ix] = (mp_digit)t; - } - - /* [optional] store the remainder */ - if (d != NULL) { - *d = (mp_digit)w; - } - - /* [optional] store the quotient */ - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; -} - -/* multiplication using the Toom-Cook 3-way algorithm - * - * Much more complicated than Karatsuba but has a lower - * asymptotic running time of O(N**1.464). This algorithm is - * only particularly useful on VERY large inputs - * (we're talking 1000s of digits here...). -*/ -static int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) -{ - mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = MIN(a->used, b->used) / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - mp_mod_2d(&a1, DIGIT_BIT * B, &a1); - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* b = b2 * B**2 + b1 * B + b0 */ - if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(b, &b1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b1, B); - mp_mod_2d(&b1, DIGIT_BIT * B, &b1); - - if ((res = mp_copy(b, &b2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b2, B*2); - - /* w0 = a0*b0 */ - if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * b2 */ - if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, - 2 small divisions and 1 small multiplication - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL); - return res; -} - -#define TOOM_MUL_CUTOFF 350 -#define KARATSUBA_MUL_CUTOFF 80 - -/* c = |a| * |b| using Karatsuba Multiplication using - * three half size multiplications - * - * Let B represent the radix [e.g. 2**DIGIT_BIT] and - * let n represent half of the number of digits in - * the min(a,b) - * - * a = a1 * B**n + a0 - * b = b1 * B**n + b0 - * - * Then, a * b => - a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0 - * - * Note that a1b1 and a0b0 are used twice and only need to be - * computed once. So in total three half size (half # of - * digit) multiplications are performed, a0b0, a1b1 and - * (a1+b1)(a0+b0) - * - * Note that a multiplication of half the digits requires - * 1/4th the number of single precision multiplications so in - * total after one call 25% of the single precision multiplications - * are saved. Note also that the call to mp_mul can end up back - * in this function if the a0, a1, b0, or b1 are above the threshold. - * This is known as divide-and-conquer and leads to the famous - * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than - * the standard O(N**2) that the baseline/comba methods use. - * Generally though the overhead of this method doesn't pay off - * until a certain size (N ~ 80) is reached. - */ -static int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x0, x1, y0, y1, t1, x0y0, x1y1; - int B; - int err; - - /* default the return code to an error */ - err = MP_MEM; - - /* min # of digits */ - B = MIN (a->used, b->used); - - /* now divide in two */ - B = (int)((unsigned)B >> 1); - - /* init copy all the temps */ - if (mp_init_size (&x0, B) != MP_OKAY) - goto ERR; - if (mp_init_size (&x1, a->used - B) != MP_OKAY) - goto X0; - if (mp_init_size (&y0, B) != MP_OKAY) - goto X1; - if (mp_init_size (&y1, b->used - B) != MP_OKAY) - goto Y0; - - /* init temps */ - if (mp_init_size (&t1, B * 2) != MP_OKAY) - goto Y1; - if (mp_init_size (&x0y0, B * 2) != MP_OKAY) - goto T1; - if (mp_init_size (&x1y1, B * 2) != MP_OKAY) - goto X0Y0; - - /* now shift the digits */ - x0.used = y0.used = B; - x1.used = a->used - B; - y1.used = b->used - B; - - { - int x; - mp_digit *tmpa, *tmpb, *tmpx, *tmpy; - - /* we copy the digits directly instead of using higher level functions - * since we also need to shift the digits - */ - tmpa = a->dp; - tmpb = b->dp; - - tmpx = x0.dp; - tmpy = y0.dp; - for (x = 0; x < B; x++) { - *tmpx++ = *tmpa++; - *tmpy++ = *tmpb++; - } - - tmpx = x1.dp; - for (x = B; x < a->used; x++) { - *tmpx++ = *tmpa++; - } - - tmpy = y1.dp; - for (x = B; x < b->used; x++) { - *tmpy++ = *tmpb++; - } - } - - /* only need to clamp the lower words since by definition the - * upper words x1/y1 must have a known number of digits - */ - mp_clamp (&x0); - mp_clamp (&y0); - - /* now calc the products x0y0 and x1y1 */ - /* after this x0 is no longer required, free temp [x0==t2]! */ - if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY) - goto X1Y1; /* x0y0 = x0*y0 */ - if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY) - goto X1Y1; /* x1y1 = x1*y1 */ - - /* now calc x1+x0 and y1+y0 */ - if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = x1 - x0 */ - if (s_mp_add (&y1, &y0, &x0) != MP_OKAY) - goto X1Y1; /* t2 = y1 - y0 */ - if (mp_mul (&t1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */ - - /* add x0y0 */ - if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY) - goto X1Y1; /* t2 = x0y0 + x1y1 */ - if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */ - - /* shift by B */ - if (mp_lshd (&t1, B) != MP_OKAY) - goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */ - if (mp_lshd (&x1y1, B * 2) != MP_OKAY) - goto X1Y1; /* x1y1 = x1y1 << 2*B */ - - if (mp_add (&x0y0, &t1, &t1) != MP_OKAY) - goto X1Y1; /* t1 = x0y0 + t1 */ - if (mp_add (&t1, &x1y1, c) != MP_OKAY) - goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */ - - /* Algorithm succeeded set the return code to MP_OKAY */ - err = MP_OKAY; - -X1Y1:mp_clear (&x1y1); -X0Y0:mp_clear (&x0y0); -T1:mp_clear (&t1); -Y1:mp_clear (&y1); -Y0:mp_clear (&y0); -X1:mp_clear (&x1); -X0:mp_clear (&x0); -ERR: - return err; -} - -/* Fast (comba) multiplier - * - * This is the fast column-array [comba] multiplier. It is - * designed to compute the columns of the product first - * then handle the carries afterwards. This has the effect - * of making the nested loops that compute the columns very - * simple and schedulable on super-scalar processors. - * - * This has been modified to produce a variable number of - * digits of output so if say only a half-product is required - * you don't have to compute the upper half (a feature - * required for fast Barrett reduction). - * - * Based on Algorithm 14.12 on pp.595 of HAC. - * - */ -static int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; - /*LINTED*/ - mp_digit W[MP_WARRAY]; - mp_word _W; - - /* grow the destination as required */ - if (c->alloc < digs) { - if ((res = mp_grow (c, digs)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = MIN(digs, a->used + b->used); - - /* clear the carry */ - _W = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty; - int iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; ++iz) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - mp_digit *tmpc; - tmpc = c->dp; - for (ix = 0; ix < pa+1; ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - return MP_OKAY; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_fast_s_mp_mul_digs.c,v $ */ -/* Revision: 1.2 $ */ -/* Date: 2011/03/18 16:22:09 $ */ - - -/* multiplies |a| * |b| and only computes upto digs digits of result - * HAC pp. 595, Algorithm 14.12 Modified so you can control how - * many digits of output are created. - */ -static int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; - - /* can we use the fast multiplier? */ - if (((unsigned)(digs) < MP_WARRAY) && - MIN (a->used, b->used) < - (1 << (unsigned)((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_s_mp_mul_digs (a, b, c, digs); - } - - if ((res = mp_init_size (&t, digs)) != MP_OKAY) { - return res; - } - t.used = digs; - - /* compute the digits of the product directly */ - pa = a->used; - for (ix = 0; ix < pa; ix++) { - /* set the carry to zero */ - u = 0; - - /* limit ourselves to making digs digits of output */ - pb = MIN (b->used, digs - ix); - - /* setup some aliases */ - /* copy of the digit from a used within the nested loop */ - tmpx = a->dp[ix]; - - /* an alias for the destination shifted ix places */ - tmpt = t.dp + ix; - - /* an alias for the digits of b */ - tmpy = b->dp; - - /* compute the columns of the output and propagate the carry */ - for (iy = 0; iy < pb; iy++) { - /* compute the column as a mp_word */ - r = ((mp_word)*tmpt) + - ((mp_word)tmpx) * ((mp_word)*tmpy++) + - ((mp_word) u); - - /* the new column is the lower part of the result */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get the carry word from the result */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - /* set carry if it is placed below digs */ - if (ix + iy < digs) { - *tmpt = u; - } - } - - mp_clamp (&t); - mp_exch (&t, c); - - mp_clear (&t); - return MP_OKAY; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_s_mp_mul_digs.c,v $ */ -/* Revision: 1.3 $ */ -/* Date: 2011/03/18 16:43:04 $ */ - -/* high level multiplication (handles sign) */ -static int -mp_mul(mp_int * a, mp_int * b, mp_int * c) -{ - int res, neg; - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - - /* use Toom-Cook? */ - if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { - res = mp_toom_mul(a, b, c); - } else - /* use Karatsuba? */ - if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { - res = mp_karatsuba_mul (a, b, c); - } else - { - /* can we use the fast multiplier? - * - * The fast multiplier can be used if the output will - * have less than MP_WARRAY digits and the number of - * digits won't affect carry propagation - */ - int digs = a->used + b->used + 1; - - if (((unsigned)digs < MP_WARRAY) && - MIN(a->used, b->used) <= - (1 << (unsigned)((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - res = fast_s_mp_mul_digs (a, b, c, digs); - } else - res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ - - } - c->sign = (c->used > 0) ? neg : MP_ZPOS; - return res; -} - -/* this is a modified version of fast_s_mul_digs that only produces - * output digits *above* digs. See the comments for fast_s_mul_digs - * to see how it works. - * - * This is used in the Barrett reduction since for one of the multiplications - * only the higher digits were needed. This essentially halves the work. - * - * Based on Algorithm 14.12 on pp.595 of HAC. - */ -static int -fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY]; - mp_word _W; - - /* grow the destination as required */ - pa = a->used + b->used; - if (c->alloc < pa) { - if ((res = mp_grow (c, pa)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = a->used + b->used; - _W = 0; - for (ix = digs; ix < pa; ix++) { - int tx, ty, iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially its - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - mp_digit *tmpc; - - tmpc = c->dp + digs; - for (ix = digs; ix < pa; ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - return MP_OKAY; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_fast_s_mp_mul_high_digs.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -/* multiplies |a| * |b| and does not compute the lower digs digits - * [meant to get the higher part of the product] - */ -static int -s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; - - /* can we use the fast multiplier? */ - if (((unsigned)(a->used + b->used + 1) < MP_WARRAY) - && MIN (a->used, b->used) < (1 << (unsigned)((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_s_mp_mul_high_digs (a, b, c, digs); - } - - if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { - return res; - } - t.used = a->used + b->used + 1; - - pa = a->used; - pb = b->used; - for (ix = 0; ix < pa; ix++) { - /* clear the carry */ - u = 0; - - /* left hand side of A[ix] * B[iy] */ - tmpx = a->dp[ix]; - - /* alias to the address of where the digits will be stored */ - tmpt = &(t.dp[digs]); - - /* alias for where to read the right hand side from */ - tmpy = b->dp + (digs - ix); - - for (iy = digs - ix; iy < pb; iy++) { - /* calculate the double precision result */ - r = ((mp_word)*tmpt) + - ((mp_word)tmpx) * ((mp_word)*tmpy++) + - ((mp_word) u); - - /* get the lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* carry the carry */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - *tmpt = u; - } - mp_clamp (&t); - mp_exch (&t, c); - mp_clear (&t); - return MP_OKAY; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_s_mp_mul_high_digs.c,v $ */ -/* Revision: 1.3 $ */ -/* Date: 2011/03/18 16:43:04 $ */ - -/* reduces x mod m, assumes 0 < x < m**2, mu is - * precomputed via mp_reduce_setup. - * From HAC pp.604 Algorithm 14.42 - */ -static int -mp_reduce (mp_int * x, mp_int * m, mp_int * mu) -{ - mp_int q; - int res, um = m->used; - - /* q = x */ - if ((res = mp_init_copy (&q, x)) != MP_OKAY) { - return res; - } - - /* q1 = x / b**(k-1) */ - mp_rshd (&q, um - 1); - - /* according to HAC this optimization is ok */ - if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { - if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { - goto CLEANUP; - } - } else { - if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { - goto CLEANUP; - } - } - - /* q3 = q2 / b**(k+1) */ - mp_rshd (&q, um + 1); - - /* x = x mod b**(k+1), quick (no division) */ - if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { - goto CLEANUP; - } - - /* q = q * m mod b**(k+1), quick (no division) */ - if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { - goto CLEANUP; - } - - /* x = x - q */ - if ((res = mp_sub (x, &q, x)) != MP_OKAY) { - goto CLEANUP; - } - - /* If x < 0, add b**(k+1) to it */ - if (mp_cmp_d (x, 0) == MP_LT) { - mp_set (&q, 1); - if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) - goto CLEANUP; - if ((res = mp_add (x, &q, x)) != MP_OKAY) - goto CLEANUP; - } - - /* Back off if it's too big */ - while (mp_cmp (x, m) != MP_LT) { - if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { - goto CLEANUP; - } - } - -CLEANUP: - mp_clear (&q); - - return res; -} - -/* determines the setup value */ -static int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) -{ - int res; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { - goto ERR; - } - - if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear(&tmp); - return res; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_reduce_2k_setup_l.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -/* reduces a modulo n where n is of the form 2**p - d - This differs from reduce_2k since "d" can be larger - than a single digit. -*/ -static int -mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - /* q = q * d */ - if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { - goto ERR; - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - s_mp_sub(a, n, a); - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_reduce_2k_l.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -/* squaring using Toom-Cook 3-way algorithm */ -static int -mp_toom_sqr(mp_int *a, mp_int *b) -{ - mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = a->used / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - mp_mod_2d(&a1, DIGIT_BIT * B, &a1); - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* w0 = a0*a0 */ - if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * a2 */ - if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))**2 */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))**2 */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)**2 */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); - return res; -} - - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_toom_sqr.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -/* Karatsuba squaring, computes b = a*a using three - * half size squarings - * - * See comments of karatsuba_mul for details. It - * is essentially the same algorithm but merely - * tuned to perform recursive squarings. - */ -static int mp_karatsuba_sqr (mp_int * a, mp_int * b) -{ - mp_int x0, x1, t1, t2, x0x0, x1x1; - int B, err; - - err = MP_MEM; - - /* min # of digits */ - B = a->used; - - /* now divide in two */ - B = (unsigned)B >> 1; - - /* init copy all the temps */ - if (mp_init_size (&x0, B) != MP_OKAY) - goto ERR; - if (mp_init_size (&x1, a->used - B) != MP_OKAY) - goto X0; - - /* init temps */ - if (mp_init_size (&t1, a->used * 2) != MP_OKAY) - goto X1; - if (mp_init_size (&t2, a->used * 2) != MP_OKAY) - goto T1; - if (mp_init_size (&x0x0, B * 2) != MP_OKAY) - goto T2; - if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY) - goto X0X0; - - { - int x; - mp_digit *dst, *src; - - src = a->dp; - - /* now shift the digits */ - dst = x0.dp; - for (x = 0; x < B; x++) { - *dst++ = *src++; - } - - dst = x1.dp; - for (x = B; x < a->used; x++) { - *dst++ = *src++; - } - } - - x0.used = B; - x1.used = a->used - B; - - mp_clamp (&x0); - - /* now calc the products x0*x0 and x1*x1 */ - if (mp_sqr (&x0, &x0x0) != MP_OKAY) - goto X1X1; /* x0x0 = x0*x0 */ - if (mp_sqr (&x1, &x1x1) != MP_OKAY) - goto X1X1; /* x1x1 = x1*x1 */ - - /* now calc (x1+x0)**2 */ - if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) - goto X1X1; /* t1 = x1 - x0 */ - if (mp_sqr (&t1, &t1) != MP_OKAY) - goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ - - /* add x0y0 */ - if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) - goto X1X1; /* t2 = x0x0 + x1x1 */ - if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY) - goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */ - - /* shift by B */ - if (mp_lshd (&t1, B) != MP_OKAY) - goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */ - if (mp_lshd (&x1x1, B * 2) != MP_OKAY) - goto X1X1; /* x1x1 = x1x1 << 2*B */ - - if (mp_add (&x0x0, &t1, &t1) != MP_OKAY) - goto X1X1; /* t1 = x0x0 + t1 */ - if (mp_add (&t1, &x1x1, b) != MP_OKAY) - goto X1X1; /* t1 = x0x0 + t1 + x1x1 */ - - err = MP_OKAY; - -X1X1:mp_clear (&x1x1); -X0X0:mp_clear (&x0x0); -T2:mp_clear (&t2); -T1:mp_clear (&t1); -X1:mp_clear (&x1); -X0:mp_clear (&x0); -ERR: - return err; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_karatsuba_sqr.c,v $ */ -/* Revision: 1.2 $ */ -/* Date: 2011/03/12 23:43:54 $ */ - -/* the jist of squaring... - * you do like mult except the offset of the tmpx [one that - * starts closer to zero] can't equal the offset of tmpy. - * So basically you set up iy like before then you min it with - * (ty-tx) so that it never happens. You double all those - * you add in the inner loop - -After that loop you do the squares and add them in. -*/ - -static int fast_s_mp_sqr (mp_int * a, mp_int * b) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY], *tmpx; - mp_word W1; - - /* grow the destination as required */ - pa = a->used + a->used; - if (b->alloc < pa) { - if ((res = mp_grow (b, pa)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - W1 = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty, iy; - mp_word _W; - mp_digit *tmpy; - - /* clear counter */ - _W = 0; - - /* get offsets into the two bignums */ - ty = MIN(a->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = a->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* now for squaring tx can never equal ty - * we halve the distance since they approach at a rate of 2x - * and we have to round because odd cases need to be executed - */ - iy = MIN(iy, (int)((unsigned)(ty-tx+1)>>1)); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* double the inner product and add carry */ - _W = _W + _W + W1; - - /* even columns have the square term in them */ - if ((ix&1) == 0) { - _W += ((mp_word)a->dp[(unsigned)ix>>1])*((mp_word)a->dp[(unsigned)ix>>1]); - } - - /* store it */ - W[ix] = (mp_digit)(_W & MP_MASK); - - /* make next carry */ - W1 = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = b->used; - b->used = a->used+a->used; - - { - mp_digit *tmpb; - tmpb = b->dp; - for (ix = 0; ix < pa; ix++) { - *tmpb++ = W[ix] & MP_MASK; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpb++ = 0; - } - } - mp_clamp (b); - return MP_OKAY; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_fast_s_mp_sqr.c,v $ */ -/* Revision: 1.3 $ */ -/* Date: 2011/03/18 16:43:04 $ */ - -/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ -static int -s_mp_sqr (mp_int * a, mp_int * b) -{ - mp_int t; - int res, ix, iy, pa; - mp_word r; - mp_digit u, tmpx, *tmpt; - - pa = a->used; - if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { - return res; - } - - /* default used is maximum possible size */ - t.used = 2*pa + 1; - - for (ix = 0; ix < pa; ix++) { - /* first calculate the digit at 2*ix */ - /* calculate double precision result */ - r = ((mp_word) t.dp[2*ix]) + - ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); - - /* store lower part in result */ - t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get the carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* left hand side of A[ix] * A[iy] */ - tmpx = a->dp[ix]; - - /* alias for where to store the results */ - tmpt = t.dp + (2*ix + 1); - - for (iy = ix + 1; iy < pa; iy++) { - /* first calculate the product */ - r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); - - /* now calculate the double precision result, note we use - * addition instead of *2 since it's easier to optimize - */ - r = ((mp_word) *tmpt) + r + r + ((mp_word) u); - - /* store lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - /* propagate upwards */ - while (u != ((mp_digit) 0)) { - r = ((mp_word) *tmpt) + ((mp_word) u); - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - } - - mp_clamp (&t); - mp_exch (&t, b); - mp_clear (&t); - return MP_OKAY; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_s_mp_sqr.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -#define TOOM_SQR_CUTOFF 400 -#define KARATSUBA_SQR_CUTOFF 120 - -/* computes b = a*a */ -static int -mp_sqr (mp_int * a, mp_int * b) -{ - int res; - - /* use Toom-Cook? */ - if (a->used >= TOOM_SQR_CUTOFF) { - res = mp_toom_sqr(a, b); - /* Karatsuba? */ - } else -if (a->used >= KARATSUBA_SQR_CUTOFF) { - res = mp_karatsuba_sqr (a, b); - } else - { - /* can we use the fast comba multiplier? */ - if (((unsigned)a->used * 2 + 1) < MP_WARRAY && - a->used < - (1 << (unsigned)(sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { - res = fast_s_mp_sqr (a, b); - } else - res = s_mp_sqr (a, b); - } - b->sign = MP_ZPOS; - return res; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_sqr.c,v $ */ -/* Revision: 1.3 $ */ -/* Date: 2011/03/18 16:43:04 $ */ - -#define TAB_SIZE 256 - -static int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) -{ - mp_int M[TAB_SIZE], res, mu; - mp_digit buf; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - int (*redux)(mp_int*,mp_int*,mp_int*); - - /* find window size */ - x = mp_count_bits (X); - if (x <= 7) { - winsize = 2; - } else if (x <= 36) { - winsize = 3; - } else if (x <= 140) { - winsize = 4; - } else if (x <= 450) { - winsize = 5; - } else if (x <= 1303) { - winsize = 6; - } else if (x <= 3529) { - winsize = 7; - } else { - winsize = 8; - } - - /* init M array */ - /* init first cell */ - if ((err = mp_init(&M[1])) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init(&M[x])) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* create mu, used for Barrett reduction */ - if ((err = mp_init (&mu)) != MP_OKAY) { - goto LBL_M; - } - - if (redmode == 0) { - if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce; - } else { - if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce_2k_l; - } - - /* create M table - * - * The M table contains powers of the base, - * e.g. M[x] = G**x mod P - * - * The first half of the table is not - * computed though accept for M[0] and M[1] - */ - if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { - goto LBL_MU; - } - - /* compute the value at M[1<<(winsize-1)] by squaring - * M[1] (winsize-1) times - */ - if ((err = mp_copy ( &M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_MU; - } - - for (x = 0; x < (winsize - 1); x++) { - /* square it */ - if ((err = mp_sqr (&M[1 << (winsize - 1)], - &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_MU; - } - - /* reduce modulo P */ - if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) - * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) - */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_MU; - } - if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* setup result */ - if ((err = mp_init (&res)) != MP_OKAY) { - goto LBL_MU; - } - mp_set (&res, 1); - - /* set initial mode and bit cnt */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - bitcpy = 0; - bitbuf = 0; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits */ - if (digidx == -1) { - break; - } - /* read next digit and reset the bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int) DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (unsigned)(buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; - buf <<= (mp_digit)1; - - /* if the bit is zero and mode == 0 then we ignore it - * These represent the leading zero bits before the first 1 bit - * in the exponent. Technically this opt is not required but it - * does lower the # of trivial squaring/reductions used - */ - if (mode == 0 && y == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we square */ - if (mode == 1 && y == 0) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - continue; - } - - /* else we add it to the window */ - bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; - - if (bitcpy == winsize) { - /* ok window is filled so square as required and multiply */ - /* square first */ - for (x = 0; x < winsize; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - - /* empty window and reset */ - bitcpy = 0; - bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then square/multiply */ - if (mode == 2 && bitcpy > 0) { - /* square then multiply if the bit is set */ - for (x = 0; x < bitcpy; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_MU:mp_clear (&mu); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} - -/* determines if a number is a valid DR modulus */ -static int -mp_dr_is_modulus(mp_int *a) -{ - int ix; - - /* must be at least two digits */ - if (a->used < 2) { - return 0; - } - - /* must be of the form b**k - a [a <= b] so all - * but the first digit must be equal to -1 (mod b). - */ - for (ix = 1; ix < a->used; ix++) { - if (a->dp[ix] != MP_MASK) { - return 0; - } - } - return 1; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_dr_is_modulus.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -/* determines if mp_reduce_2k can be used */ -static int mp_reduce_is_2k(mp_int *a) -{ - int ix, iy, iw; - mp_digit iz; - - if (a->used == 0) { - return MP_NO; - } else if (a->used == 1) { - return MP_YES; - } else if (a->used > 1) { - iy = mp_count_bits(a); - iz = 1; - iw = 1; - - /* Test every bit from the second digit up, must be 1 */ - for (ix = DIGIT_BIT; ix < iy; ix++) { - if ((a->dp[iw] & iz) == 0) { - return MP_NO; - } - iz <<= 1; - if (iz > (mp_digit)MP_MASK) { - ++iw; - iz = 1; - } - } - } - return MP_YES; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_reduce_is_2k.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - - -/* d = a * b (mod c) */ -static int -mp_mulmod (mp_int *d, mp_int * a, mp_int * b, mp_int * c) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_mul (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_mulmod.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -/* setups the montgomery reduction stuff */ -static int -mp_montgomery_setup (mp_int * n, mp_digit * rho) -{ - mp_digit x, b; - -/* fast inversion mod 2**k - * - * Based on the fact that - * - * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) - * => 2*X*A - X*X*A*A = 1 - * => 2*(1) - (1) = 1 - */ - b = n->dp[0]; - - if ((b & 1) == 0) { - return MP_VAL; - } - - x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ - x *= 2 - b * x; /* here x*a==1 mod 2**8 */ - x *= 2 - b * x; /* here x*a==1 mod 2**16 */ - x *= 2 - b * x; /* here x*a==1 mod 2**32 */ - if (/*CONSTCOND*/sizeof(mp_digit) == 8) { - x *= 2 - b * x; /* here x*a==1 mod 2**64 */ - } - - /* rho = -1/m mod b */ - *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; - - return MP_OKAY; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_montgomery_setup.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -/* computes xR**-1 == x (mod N) via Montgomery Reduction - * - * This is an optimized implementation of montgomery_reduce - * which uses the comba method to quickly calculate the columns of the - * reduction. - * - * Based on Algorithm 14.32 on pp.601 of HAC. -*/ -static int -fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, olduse; - /*LINTED*/ - mp_word W[MP_WARRAY]; - - /* get old used count */ - olduse = x->used; - - /* grow a as required */ - if (x->alloc < n->used + 1) { - if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { - return res; - } - } - - /* first we have to get the digits of the input into - * an array of double precision words W[...] - */ - { - mp_word *_W; - mp_digit *tmpx; - - /* alias for the W[] array */ - _W = W; - - /* alias for the digits of x*/ - tmpx = x->dp; - - /* copy the digits of a into W[0..a->used-1] */ - for (ix = 0; ix < x->used; ix++) { - *_W++ = *tmpx++; - } - - /* zero the high words of W[a->used..m->used*2] */ - for (; ix < n->used * 2 + 1; ix++) { - *_W++ = 0; - } - } - - /* now we proceed to zero successive digits - * from the least significant upwards - */ - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * m' mod b - * - * We avoid a double precision multiplication (which isn't required) - * by casting the value down to a mp_digit. Note this requires - * that W[ix-1] have the carry cleared (see after the inner loop) - */ - mp_digit mu; - mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); - - /* a = a + mu * m * b**i - * - * This is computed in place and on the fly. The multiplication - * by b**i is handled by offseting which columns the results - * are added to. - * - * Note the comba method normally doesn't handle carries in the - * inner loop In this case we fix the carry from the previous - * column since the Montgomery reduction requires digits of the - * result (so far) [see above] to work. This is - * handled by fixing up one carry after the inner loop. The - * carry fixups are done in order so after these loops the - * first m->used words of W[] have the carries fixed - */ - { - int iy; - mp_digit *tmpn; - mp_word *_W; - - /* alias for the digits of the modulus */ - tmpn = n->dp; - - /* Alias for the columns set by an offset of ix */ - _W = W + ix; - - /* inner loop */ - for (iy = 0; iy < n->used; iy++) { - *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); - } - } - - /* now fix carry for next digit, W[ix+1] */ - W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); - } - - /* now we have to propagate the carries and - * shift the words downward [all those least - * significant digits we zeroed]. - */ - { - mp_digit *tmpx; - mp_word *_W, *_W1; - - /* nox fix rest of carries */ - - /* alias for current word */ - _W1 = W + ix; - - /* alias for next word, where the carry goes */ - _W = W + ++ix; - - for (; ix <= n->used * 2 + 1; ix++) { - *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); - } - - /* copy out, A = A/b**n - * - * The result is A/b**n but instead of converting from an - * array of mp_word to mp_digit than calling mp_rshd - * we just copy them in the right order - */ - - /* alias for destination word */ - tmpx = x->dp; - - /* alias for shifted double precision result */ - _W = W + n->used; - - for (ix = 0; ix < n->used + 1; ix++) { - *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); - } - - /* zero oldused digits, if the input a was larger than - * m->used+1 we'll have to clear the digits - */ - for (; ix < olduse; ix++) { - *tmpx++ = 0; - } - } - - /* set the max used and clamp */ - x->used = n->used + 1; - mp_clamp (x); - - /* if A >= m then A = A - m */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - return MP_OKAY; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_fast_mp_montgomery_reduce.c,v $ */ -/* Revision: 1.2 $ */ -/* Date: 2011/03/18 16:22:09 $ */ - -/* computes xR**-1 == x (mod N) via Montgomery Reduction */ -static int -mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, digs; - mp_digit mu; - - /* can the fast reduction [comba] method be used? - * - * Note that unlike in mul you're safely allowed *less* - * than the available columns [255 per default] since carries - * are fixed up in the inner loop. - */ - digs = n->used * 2 + 1; - if (((unsigned)digs < MP_WARRAY) && - n->used < - (1 << (unsigned)((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_mp_montgomery_reduce (x, n, rho); - } - - /* grow the input as required */ - if (x->alloc < digs) { - if ((res = mp_grow (x, digs)) != MP_OKAY) { - return res; - } - } - x->used = digs; - - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * rho mod b - * - * The value of rho must be precalculated via - * montgomery_setup() such that - * it equals -1/n0 mod b this allows the - * following inner loop to reduce the - * input one digit at a time - */ - mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK); - - /* a = a + mu * m * b**i */ - { - int iy; - mp_digit *tmpn, *tmpx, u; - mp_word r; - - /* alias for digits of the modulus */ - tmpn = n->dp; - - /* alias for the digits of x [the input] */ - tmpx = x->dp + ix; - - /* set the carry to zero */ - u = 0; - - /* Multiply and add in place */ - for (iy = 0; iy < n->used; iy++) { - /* compute product and sum */ - r = ((mp_word)mu) * ((mp_word)*tmpn++) + - ((mp_word) u) + ((mp_word) * tmpx); - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* fix digit */ - *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); - } - /* At this point the ix'th digit of x should be zero */ - - - /* propagate carries upwards as required*/ - while (u) { - *tmpx += u; - u = *tmpx >> DIGIT_BIT; - *tmpx++ &= MP_MASK; - } - } - } - - /* at this point the n.used'th least - * significant digits of x are all zero - * which means we can shift x to the - * right by n.used digits and the - * residue is unchanged. - */ - - /* x = x/b**n.used */ - mp_clamp(x); - mp_rshd (x, n->used); - - /* if x >= n then x = x - n */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - - return MP_OKAY; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_montgomery_reduce.c,v $ */ -/* Revision: 1.3 $ */ -/* Date: 2011/03/18 16:43:04 $ */ - -/* determines the setup value */ -static void -mp_dr_setup(mp_int *a, mp_digit *d) -{ - /* the casts are required if DIGIT_BIT is one less than - * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] - */ - *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - - ((mp_word)a->dp[0])); -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_dr_setup.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. - * - * Based on algorithm from the paper - * - * "Generating Efficient Primes for Discrete Log Cryptosystems" - * Chae Hoon Lim, Pil Joong Lee, - * POSTECH Information Research Laboratories - * - * The modulus must be of a special format [see manual] - * - * Has been modified to use algorithm 7.10 from the LTM book instead - * - * Input x must be in the range 0 <= x <= (n-1)**2 - */ -static int -mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) -{ - int err, i, m; - mp_word r; - mp_digit mu, *tmpx1, *tmpx2; - - /* m = digits in modulus */ - m = n->used; - - /* ensure that "x" has at least 2m digits */ - if (x->alloc < m + m) { - if ((err = mp_grow (x, m + m)) != MP_OKAY) { - return err; - } - } - -/* top of loop, this is where the code resumes if - * another reduction pass is required. - */ -top: - /* aliases for digits */ - /* alias for lower half of x */ - tmpx1 = x->dp; - - /* alias for upper half of x, or x/B**m */ - tmpx2 = x->dp + m; - - /* set carry to zero */ - mu = 0; - - /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ - for (i = 0; i < m; i++) { - r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; - *tmpx1++ = (mp_digit)(r & MP_MASK); - mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); - } - - /* set final carry */ - *tmpx1++ = mu; - - /* zero words above m */ - for (i = m + 1; i < x->used; i++) { - *tmpx1++ = 0; - } - - /* clamp, sub and return */ - mp_clamp (x); - - /* if x >= n then subtract and reduce again - * Each successive "recursion" makes the input smaller and smaller. - */ - if (mp_cmp_mag (x, n) != MP_LT) { - s_mp_sub(x, n, x); - goto top; - } - return MP_OKAY; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_dr_reduce.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -/* determines the setup value */ -static int -mp_reduce_2k_setup(mp_int *a, mp_digit *d) -{ - int res, p; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(a); - if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - *d = tmp.dp[0]; - mp_clear(&tmp); - return MP_OKAY; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_reduce_2k_setup.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -/* reduces a modulo n where n is of the form 2**p - d */ -static int -mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (d != 1) { - /* q = q * d */ - if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { - goto ERR; - } - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - s_mp_sub(a, n, a); - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_reduce_2k.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -/* - * shifts with subtractions when the result is greater than b. - * - * The method is slightly modified to shift B unconditionally upto just under - * the leading bit of b. This saves alot of multiple precision shifting. - */ -static int -mp_montgomery_calc_normalization (mp_int * a, mp_int * b) -{ - int x, bits, res; - - /* how many bits of last digit does b use */ - bits = mp_count_bits (b) % DIGIT_BIT; - - if (b->used > 1) { - if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { - return res; - } - } else { - mp_set(a, 1); - bits = 1; - } - - - /* now compute C = A * B mod b */ - for (x = bits - 1; x < (int)DIGIT_BIT; x++) { - if ((res = mp_mul_2 (a, a)) != MP_OKAY) { - return res; - } - if (mp_cmp_mag (a, b) != MP_LT) { - if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { - return res; - } - } - } - - return MP_OKAY; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_montgomery_calc_normalization.c,v $ */ -/* Revision: 1.1.1.1 $ */ -/* Date: 2011/03/12 22:58:18 $ */ - -/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 - * - * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. - * The value of k changes based on the size of the exponent. - * - * Uses Montgomery or Diminished Radix reduction [whichever appropriate] - */ - -#define TAB_SIZE 256 - -static int -mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) -{ - mp_int M[TAB_SIZE], res; - mp_digit buf, mp; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - - /* use a pointer to the reduction algorithm. This allows us to use - * one of many reduction algorithms without modding the guts of - * the code with if statements everywhere. - */ - int (*redux)(mp_int*,mp_int*,mp_digit); - - /* find window size */ - x = mp_count_bits (X); - if (x <= 7) { - winsize = 2; - } else if (x <= 36) { - winsize = 3; - } else if (x <= 140) { - winsize = 4; - } else if (x <= 450) { - winsize = 5; - } else if (x <= 1303) { - winsize = 6; - } else if (x <= 3529) { - winsize = 7; - } else { - winsize = 8; - } - - /* init M array */ - /* init first cell */ - if ((err = mp_init(&M[1])) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init(&M[x])) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* determine and setup reduction code */ - if (redmode == 0) { - /* now setup montgomery */ - if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { - goto LBL_M; - } - - /* automatically pick the comba one if available (saves quite a few calls/ifs) */ - if (((unsigned)(P->used * 2 + 1) < MP_WARRAY) && - P->used < (1 << (unsigned)((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - redux = fast_mp_montgomery_reduce; - } else - { - /* use slower baseline Montgomery method */ - redux = mp_montgomery_reduce; - } - } else if (redmode == 1) { - /* setup DR reduction for moduli of the form B**k - b */ - mp_dr_setup(P, &mp); - redux = mp_dr_reduce; - } else { - /* setup DR reduction for moduli of the form 2**k - b */ - if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { - goto LBL_M; - } - redux = mp_reduce_2k; - } - - /* setup result */ - if ((err = mp_init (&res)) != MP_OKAY) { - goto LBL_M; - } - - /* create M table - * - - * - * The first half of the table is not computed though accept for M[0] and M[1] - */ - - if (redmode == 0) { - /* now we need R mod m */ - if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { - goto LBL_RES; - } - - /* now set M[1] to G * R mod m */ - if ((err = mp_mulmod (&M[1], G, &res, P)) != MP_OKAY) { - goto LBL_RES; - } - } else { - mp_set(&res, 1); - if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } - } - - /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ - if ((err = mp_copy ( &M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_RES; - } - - for (x = 0; x < (winsize - 1); x++) { - if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* create upper table */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[x], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* set initial mode and bit cnt */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - bitcpy = 0; - bitbuf = 0; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits so break */ - if (digidx == -1) { - break; - } - /* read next digit and reset bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int)DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (int)(mp_digit)((mp_digit)buf >> (unsigned)(DIGIT_BIT - 1)) & 1; - buf <<= (mp_digit)1; - - /* if the bit is zero and mode == 0 then we ignore it - * These represent the leading zero bits before the first 1 bit - * in the exponent. Technically this opt is not required but it - * does lower the # of trivial squaring/reductions used - */ - if (mode == 0 && y == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we square */ - if (mode == 1 && y == 0) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - continue; - } - - /* else we add it to the window */ - bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; - - if (bitcpy == winsize) { - /* ok window is filled so square as required and multiply */ - /* square first */ - for (x = 0; x < winsize; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - - /* empty window and reset */ - bitcpy = 0; - bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then square/multiply */ - if (mode == 2 && bitcpy > 0) { - /* square then multiply if the bit is set */ - for (x = 0; x < bitcpy; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - - /* get next bit of the window */ - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - if (redmode == 0) { - /* fixup result if Montgomery reduction is used - * recall that any value in a Montgomery system is - * actually multiplied by R mod n. So we have - * to reduce one more time to cancel out the factor - * of R. - */ - if ((err = redux(&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* swap res with Y */ - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} - -/* Source: /usr/cvsroot/libtommath/dist/libtommath/bn_mp_exptmod_fast.c,v $ */ -/* Revision: 1.4 $ */ -/* Date: 2011/03/18 16:43:04 $ */ - -/* this is a shell function that calls either the normal or Montgomery - * exptmod functions. Originally the call to the montgomery code was - * embedded in the normal function but that wasted alot of stack space - * for nothing (since 99% of the time the Montgomery code would be called) - */ -static int -mp_exptmod(mp_int * G, mp_int * X, mp_int * P, mp_int *Y) -{ - int dr; - - /* modulus P must be positive */ - if (P->sign == MP_NEG) { - return MP_VAL; - } - - /* if exponent X is negative we have to recurse */ - if (X->sign == MP_NEG) { - mp_int tmpG, tmpX; - int err; - - /* first compute 1/G mod P */ - if ((err = mp_init(&tmpG)) != MP_OKAY) { - return err; - } - if ((err = mp_invmod(&tmpG, G, P)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - - /* now get |X| */ - if ((err = mp_init(&tmpX)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { - mp_clear_multi(&tmpG, &tmpX, NULL); - return err; - } - - /* and now compute (1/G)**|X| instead of G**X [X < 0] */ - err = mp_exptmod(&tmpG, &tmpX, P, Y); - mp_clear_multi(&tmpG, &tmpX, NULL); - return err; - } - -/* modified diminished radix reduction */ - if (mp_reduce_is_2k_l(P) == MP_YES) { - return s_mp_exptmod(G, X, P, Y, 1); - } - - /* is it a DR modulus? */ - dr = mp_dr_is_modulus(P); - - /* if not, is it a unrestricted DR modulus? */ - if (dr == 0) { - dr = mp_reduce_is_2k(P) << 1; - } - - /* if the modulus is odd or dr != 0 use the montgomery method */ - if (BN_is_odd (P) == 1 || dr != 0) { - return mp_exptmod_fast (G, X, P, Y, dr); - } else { - /* otherwise use the generic Barrett reduction technique */ - return s_mp_exptmod (G, X, P, Y, 0); - } -} - -/* reverse an array, used for radix code */ -static void -bn_reverse(unsigned char *s, int len) -{ - int ix, iy; - unsigned char t; - - ix = 0; - iy = len - 1; - while (ix < iy) { - t = s[ix]; - s[ix] = s[iy]; - s[iy] = t; - ++ix; - --iy; - } -} - -static int -s_is_power_of_two(mp_digit b, int *p) -{ - int x; - - /* fast return if no power of two */ - if ((b==0) || (b & (b-1))) { - return 0; - } - - for (x = 0; x < DIGIT_BIT; x++) { - if (b == (((mp_digit)1)<<x)) { - *p = x; - return 1; - } - } - return 0; -} - -/* single digit division (based on routine from MPI) */ -static int -mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d) -{ - mp_int q; - mp_word w; - mp_digit t; - int res, ix; - - /* cannot divide by zero */ - if (b == 0) { - return MP_VAL; - } - - /* quick outs */ - if (b == 1 || mp_iszero(a) == 1) { - if (d != NULL) { - *d = 0; - } - if (c != NULL) { - return mp_copy(a, c); - } - return MP_OKAY; - } - - /* power of two ? */ - if (s_is_power_of_two(b, &ix) == 1) { - if (d != NULL) { - *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1); - } - if (c != NULL) { - return mp_div_2d(a, ix, c, NULL); - } - return MP_OKAY; - } - -#ifdef BN_MP_DIV_3_C - /* three? */ - if (b == 3) { - return mp_div_3(a, c, d); - } -#endif - - /* no easy answer [c'est la vie]. Just division */ - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= b) { - t = (mp_digit)(w / b); - w -= ((mp_word)t) * ((mp_word)b); - } else { - t = 0; - } - q.dp[ix] = (mp_digit)t; - } - - if (d != NULL) { - *d = (mp_digit)w; - } - - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; -} - -static int -mp_mod_d(mp_int *a, mp_digit b, mp_digit *c) -{ - return mp_div_d(a, b, NULL, c); -} - -static const mp_digit ltm_prime_tab[] = { - 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, - 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, - 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, - 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, -#ifndef MP_8BIT - 0x0083, - 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, - 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, - 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, - 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, - - 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, - 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, - 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, - 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, - 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, - 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, - 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, - 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, - - 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, - 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, - 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, - 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, - 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, - 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, - 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, - 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, - - 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, - 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, - 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, - 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, - 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, - 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, - 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, - 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 -#endif -}; - -#define PRIME_SIZE __arraycount(ltm_prime_tab) - -static int -mp_prime_is_divisible(mp_int *a, int *result) -{ - int err, ix; - mp_digit res; - - /* default to not */ - *result = MP_NO; - - for (ix = 0; ix < (int)PRIME_SIZE; ix++) { - /* what is a mod LBL_prime_tab[ix] */ - if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) { - return err; - } - - /* is the residue zero? */ - if (res == 0) { - *result = MP_YES; - return MP_OKAY; - } - } - - return MP_OKAY; -} - -/* single digit addition */ -static int -mp_add_d(mp_int *a, mp_digit b, mp_int *c) -{ - int res, ix, oldused; - mp_digit *tmpa, *tmpc, mu; - - /* grow c as required */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative and |a| >= b, call c = |a| - b */ - if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { - /* temporarily fix sign of a */ - a->sign = MP_ZPOS; - - /* c = |a| - b */ - res = mp_sub_d(a, b, c); - - /* fix sign */ - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* old number of used digits in c */ - oldused = c->used; - - /* sign always positive */ - c->sign = MP_ZPOS; - - /* source alias */ - tmpa = a->dp; - - /* destination alias */ - tmpc = c->dp; - - /* if a is positive */ - if (a->sign == MP_ZPOS) { - /* add digit, after this we're propagating - * the carry. - */ - *tmpc = *tmpa++ + b; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - - /* now handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ + mu; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - } - /* set final carry */ - ix++; - *tmpc++ = mu; - - /* setup size */ - c->used = a->used + 1; - } else { - /* a was negative and |a| < b */ - c->used = 1; - - /* the result is a single digit */ - if (a->used == 1) { - *tmpc++ = b - a->dp[0]; - } else { - *tmpc++ = b; - } - - /* setup count so the clearing of oldused - * can fall through correctly - */ - ix = 1; - } - - /* now zero to oldused */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - - return MP_OKAY; -} - -/* single digit subtraction */ -static int -mp_sub_d(mp_int *a, mp_digit b, mp_int *c) -{ - mp_digit *tmpa, *tmpc, mu; - int res, ix, oldused; - - /* grow c as required */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative just do an unsigned - * addition [with fudged signs] - */ - if (a->sign == MP_NEG) { - a->sign = MP_ZPOS; - res = mp_add_d(a, b, c); - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* setup regs */ - oldused = c->used; - tmpa = a->dp; - tmpc = c->dp; - - /* if a <= b simply fix the single digit */ - if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { - if (a->used == 1) { - *tmpc++ = b - *tmpa; - } else { - *tmpc++ = b; - } - ix = 1; - - /* negative/1digit */ - c->sign = MP_NEG; - c->used = 1; - } else { - /* positive/size */ - c->sign = MP_ZPOS; - c->used = a->used; - - /* subtract first digit */ - *tmpc = *tmpa++ - b; - mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); - *tmpc++ &= MP_MASK; - - /* handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ - mu; - mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); - *tmpc++ &= MP_MASK; - } - } - - /* zero excess digits */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - return MP_OKAY; -} - -static const int lnz[16] = { - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -/* Counts the number of lsbs which are zero before the first zero bit */ -static int -mp_cnt_lsb(mp_int *a) -{ - int x; - mp_digit q, qq; - - /* easy out */ - if (mp_iszero(a) == 1) { - return 0; - } - - /* scan lower digits until non-zero */ - for (x = 0; x < a->used && a->dp[x] == 0; x++); - q = a->dp[x]; - x *= DIGIT_BIT; - - /* now scan this digit until a 1 is found */ - if ((q & 1) == 0) { - do { - qq = q & 15; - /* LINTED previous op ensures range of qq */ - x += lnz[qq]; - q >>= 4; - } while (qq == 0); - } - return x; -} - -/* c = a * a (mod b) */ -static int -mp_sqrmod(mp_int *a, mp_int *b, mp_int *c) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_sqr (a, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, b, c); - mp_clear (&t); - return res; -} -static int -mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result) -{ - mp_int n1, y, r; - int s, j, err; - - /* default */ - *result = MP_NO; - - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } - - /* get n1 = a - 1 */ - if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { - return err; - } - if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { - goto LBL_N1; - } - - /* set 2**s * r = n1 */ - if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { - goto LBL_N1; - } - - /* count the number of least significant bits - * which are zero - */ - s = mp_cnt_lsb(&r); - - /* now divide n - 1 by 2**s */ - if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { - goto LBL_R; - } - - /* compute y = b**r mod a */ - if ((err = mp_init (&y)) != MP_OKAY) { - goto LBL_R; - } - if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { - goto LBL_Y; - } - - /* if y != 1 and y != n1 do */ - if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) { - j = 1; - /* while j <= s-1 and y != n1 */ - while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) { - if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { - goto LBL_Y; - } - - /* if y == 1 then composite */ - if (mp_cmp_d (&y, 1) == MP_EQ) { - goto LBL_Y; - } - - ++j; - } - - /* if y != n1 then composite */ - if (mp_cmp (&y, &n1) != MP_EQ) { - goto LBL_Y; - } - } - - /* probably prime now */ - *result = MP_YES; -LBL_Y:mp_clear (&y); -LBL_R:mp_clear (&r); -LBL_N1:mp_clear (&n1); - return err; -} - -/* performs a variable number of rounds of Miller-Rabin - * - * Probability of error after t rounds is no more than - - * - * Sets result to 1 if probably prime, 0 otherwise - */ -static int -mp_prime_is_prime(mp_int *a, int t, int *result) -{ - mp_int b; - int ix, err, res; - - /* default to no */ - *result = MP_NO; - - /* valid value of t? */ - if (t <= 0 || t > (int)PRIME_SIZE) { - return MP_VAL; - } - - /* is the input equal to one of the primes in the table? */ - for (ix = 0; ix < (int)PRIME_SIZE; ix++) { - if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { - *result = 1; - return MP_OKAY; - } - } - - /* first perform trial division */ - if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { - return err; - } - - /* return if it was trivially divisible */ - if (res == MP_YES) { - return MP_OKAY; - } - - /* now perform the miller-rabin rounds */ - if ((err = mp_init (&b)) != MP_OKAY) { - return err; - } - - for (ix = 0; ix < t; ix++) { - /* set the prime */ - mp_set (&b, ltm_prime_tab[ix]); - - if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { - goto LBL_B; - } - - if (res == MP_NO) { - goto LBL_B; - } - } - - /* passed the test */ - *result = MP_YES; -LBL_B:mp_clear (&b); - return err; -} - -/* returns size of ASCII reprensentation */ -static int -mp_radix_size (mp_int *a, int radix, int *size) -{ - int res, digs; - mp_int t; - mp_digit d; - - *size = 0; - - /* special case for binary */ - if (radix == 2) { - *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; - return MP_OKAY; - } - - /* make sure the radix is in range */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - if (mp_iszero(a) == MP_YES) { - *size = 2; - return MP_OKAY; - } - - /* digs is the digit count */ - digs = 0; - - /* if it's negative add one for the sign */ - if (a->sign == MP_NEG) { - ++digs; - } - - /* init a copy of the input */ - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* force temp to positive */ - t.sign = MP_ZPOS; - - /* fetch out all of the digits */ - while (mp_iszero (&t) == MP_NO) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - ++digs; - } - mp_clear (&t); - - /* return digs + 1, the 1 is for the NULL byte that would be required. */ - *size = digs + 1; - return MP_OKAY; -} - -static const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; - -/* stores a bignum as a ASCII string in a given radix (2..64) - * - * Stores upto maxlen-1 chars and always a NULL byte - */ -static int -mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the maxlen, radix */ - if (maxlen < 2 || radix < 2 || radix > 64) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == MP_YES) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - /* we have to reverse our digits later... but not the - sign!! */ - ++_s; - - /* store the flag and mark the number as positive */ - *str++ = '-'; - t.sign = MP_ZPOS; - - /* subtract a char */ - --maxlen; - } - - digs = 0; - while (mp_iszero (&t) == 0) { - if (--maxlen < 1) { - /* no more room */ - break; - } - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - /* LINTED -- radix' range is checked above, limits d's range */ - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -static char * -formatbn(const BIGNUM *a, const int radix) -{ - char *s; - int len; - - if (mp_radix_size(__UNCONST(a), radix, &len) != MP_OKAY) { - return NULL; - } - if ((s = netpgp_allocate(1, (size_t)len)) != NULL) { - if (mp_toradix_n(__UNCONST(a), s, radix, len) != MP_OKAY) { - netpgp_deallocate(s, (size_t)len); - return NULL; - } - } - return s; -} - -static int -mp_getradix_num(mp_int *a, int radix, char *s) -{ - int err, ch, neg, y; - - /* clear a */ - mp_zero(a); - - /* if first digit is - then set negative */ - if ((ch = *s++) == '-') { - neg = MP_NEG; - ch = *s++; - } else { - neg = MP_ZPOS; - } - - for (;;) { - /* find y in the radix map */ - for (y = 0; y < radix; y++) { - if (mp_s_rmap[y] == ch) { - break; - } - } - if (y == radix) { - break; - } - - /* shift up and add */ - if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { - return err; - } - if ((err = mp_add_d(a, y, a)) != MP_OKAY) { - return err; - } - - ch = *s++; - } - if (mp_cmp_d(a, 0) != MP_EQ) { - a->sign = neg; - } - - return MP_OKAY; -} - -static int -getbn(BIGNUM **a, const char *str, int radix) -{ - int len; - - if (a == NULL || str == NULL || (*a = BN_new()) == NULL) { - return 0; - } - if (mp_getradix_num(*a, radix, __UNCONST(str)) != MP_OKAY) { - return 0; - } - mp_radix_size(__UNCONST(*a), radix, &len); - return len - 1; -} - -/* d = a - b (mod c) */ -static int -mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) -{ - int res; - mp_int t; - - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_sub (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} - -/**************************************************************************/ - -/* BIGNUM emulation layer */ - -/* essentiually, these are just wrappers around the libtommath functions */ -/* usually the order of args changes */ -/* the BIGNUM API tends to have more const poisoning */ -/* these wrappers also check the arguments passed for sanity */ - -BIGNUM * -BN_bin2bn(const uint8_t *data, int len, BIGNUM *ret) -{ - if (data == NULL) { - return BN_new(); - } - if (ret == NULL) { - ret = BN_new(); - } - return (mp_read_unsigned_bin(ret, data, len) == MP_OKAY) ? ret : NULL; -} - -/* store in unsigned [big endian] format */ -int -BN_bn2bin(const BIGNUM *a, unsigned char *b) -{ - BIGNUM t; - int x; - - if (a == NULL || b == NULL) { - return -1; - } - if (mp_init_copy (&t, __UNCONST(a)) != MP_OKAY) { - return -1; - } - for (x = 0; !BN_is_zero(&t) ; ) { - b[x++] = (unsigned char) (t.dp[0] & 0xff); - if (mp_div_2d (&t, 8, &t, NULL) != MP_OKAY) { - mp_clear(&t); - return -1; - } - } - bn_reverse(b, x); - mp_clear(&t); - return x; -} - -void -BN_init(BIGNUM *a) -{ - if (a != NULL) { - mp_init(a); - } -} - -BIGNUM * -BN_new(void) -{ - BIGNUM *a; - - if ((a = netpgp_allocate(1, sizeof(*a))) != NULL) { - mp_init(a); - } - return a; -} - -/* copy, b = a */ -int -BN_copy(BIGNUM *b, const BIGNUM *a) -{ - if (a == NULL || b == NULL) { - return MP_VAL; - } - return mp_copy(__UNCONST(a), b); -} - -BIGNUM * -BN_dup(const BIGNUM *a) -{ - BIGNUM *ret; - - if (a == NULL) { - return NULL; - } - if ((ret = BN_new()) != NULL) { - BN_copy(ret, a); - } - return ret; -} - -void -BN_swap(BIGNUM *a, BIGNUM *b) -{ - if (a && b) { - mp_exch(a, b); - } -} - -int -BN_lshift(BIGNUM *r, const BIGNUM *a, int n) -{ - if (r == NULL || a == NULL || n < 0) { - return 0; - } - BN_copy(r, a); - return mp_lshd(r, n) == MP_OKAY; -} - -int -BN_lshift1(BIGNUM *r, BIGNUM *a) -{ - if (r == NULL || a == NULL) { - return 0; - } - BN_copy(r, a); - return mp_lshd(r, 1) == MP_OKAY; -} - -int -BN_rshift(BIGNUM *r, const BIGNUM *a, int n) -{ - if (r == NULL || a == NULL || n < 0) { - return MP_VAL; - } - BN_copy(r, a); - return mp_rshd(r, n) == MP_OKAY; -} - -int -BN_rshift1(BIGNUM *r, BIGNUM *a) -{ - if (r == NULL || a == NULL) { - return 0; - } - BN_copy(r, a); - return mp_rshd(r, 1) == MP_OKAY; -} - -int -BN_set_word(BIGNUM *a, BN_ULONG w) -{ - if (a == NULL) { - return 0; - } - mp_set(a, w); - return 1; -} - -int -BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) -{ - if (a == NULL || b == NULL || r == NULL) { - return 0; - } - return mp_add(__UNCONST(a), __UNCONST(b), r) == MP_OKAY; -} - -int -BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) -{ - if (a == NULL || b == NULL || r == NULL) { - return 0; - } - return mp_sub(__UNCONST(a), __UNCONST(b), r) == MP_OKAY; -} - -int -BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) -{ - if (a == NULL || b == NULL || r == NULL) { - return 0; - } - USE_ARG(ctx); - return mp_mul(__UNCONST(a), __UNCONST(b), r) == MP_OKAY; -} - -int -BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *a, const BIGNUM *d, BN_CTX *ctx) -{ - if ((dv == NULL && rem == NULL) || a == NULL || d == NULL) { - return 0; - } - USE_ARG(ctx); - return mp_div(dv, rem, __UNCONST(a), __UNCONST(d)) == MP_OKAY; -} - -void -BN_free(BIGNUM *a) -{ - if (a) { - mp_clear(a); - } -} - -void -BN_clear(BIGNUM *a) -{ - if (a) { - mp_clear(a); - } -} - -void -BN_clear_free(BIGNUM *a) -{ - if (a) { - mp_clear(a); - } -} - -int -BN_num_bytes(const BIGNUM *a) -{ - if (a == NULL) { - return MP_VAL; - } - return mp_unsigned_bin_size(__UNCONST(a)); -} - -int -BN_num_bits(const BIGNUM *a) -{ - if (a == NULL) { - return 0; - } - return mp_count_bits(a); -} - -void -BN_set_negative(BIGNUM *a, int n) -{ - if (a) { - a->sign = (n) ? MP_NEG : 0; - } -} - -int -BN_cmp(BIGNUM *a, BIGNUM *b) -{ - if (a == NULL || b == NULL) { - return MP_VAL; - } - switch(mp_cmp(a, b)) { - case MP_LT: - return -1; - case MP_GT: - return 1; - case MP_EQ: - default: - return 0; - } -} - -int -BN_mod_exp(BIGNUM *Y, BIGNUM *G, BIGNUM *X, BIGNUM *P, BN_CTX *ctx) -{ - if (Y == NULL || G == NULL || X == NULL || P == NULL) { - return MP_VAL; - } - USE_ARG(ctx); - return mp_exptmod(G, X, P, Y) == MP_OKAY; -} - -BIGNUM * -BN_mod_inverse(BIGNUM *r, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) -{ - USE_ARG(ctx); - if (r == NULL || a == NULL || n == NULL) { - return NULL; - } - return (mp_invmod(r, a, __UNCONST(n)) == MP_OKAY) ? r : NULL; -} - -int -BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) -{ - USE_ARG(ctx); - if (ret == NULL || a == NULL || b == NULL || m == NULL) { - return 0; - } - return mp_mulmod(ret, a, b, __UNCONST(m)) == MP_OKAY; -} - -BN_CTX * -BN_CTX_new(void) -{ - return netpgp_allocate(1, sizeof(BN_CTX)); -} - -void -BN_CTX_init(BN_CTX *c) -{ - if (c != NULL) { - c->arraysize = 15; - if ((c->v = netpgp_allocate(sizeof(*c->v), c->arraysize)) == NULL) { - c->arraysize = 0; - } - } -} - -BIGNUM * -BN_CTX_get(BN_CTX *ctx) -{ - if (ctx == NULL || ctx->v == NULL || ctx->arraysize == 0 || ctx->count == ctx->arraysize - 1) { - return NULL; - } - return ctx->v[ctx->count++] = BN_new(); -} - -void -BN_CTX_start(BN_CTX *ctx) -{ - BN_CTX_init(ctx); -} - -void -BN_CTX_free(BN_CTX *c) -{ - unsigned i; - - if (c != NULL && c->v != NULL) { - for (i = 0 ; i < c->count ; i++) { - BN_clear_free(c->v[i]); - } - netpgp_deallocate(c->v, sizeof(*c->v) * c->arraysize); - } -} - -void -BN_CTX_end(BN_CTX *ctx) -{ - BN_CTX_free(ctx); -} - -char * -BN_bn2hex(const BIGNUM *a) -{ - return (a == NULL) ? NULL : formatbn(a, 16); -} - -char * -BN_bn2dec(const BIGNUM *a) -{ - return (a == NULL) ? NULL : formatbn(a, 10); -} - -#ifndef _KERNEL -int -BN_print_fp(FILE *fp, const BIGNUM *a) -{ - char *s; - int ret; - - if (fp == NULL || a == NULL) { - return 0; - } - s = BN_bn2hex(a); - ret = fprintf(fp, "%s", s); - netpgp_deallocate(s, strlen(s) + 1); - return ret; -} -#endif - -int -BN_rand(BIGNUM *rnd, int bits, int top, int bottom) -{ - uint64_t r; - int digits; - int i; - - if (rnd == NULL) { - return 0; - } - mp_init_size(rnd, digits = howmany(bits, DIGIT_BIT)); - for (i = 0 ; i < digits ; i++) { - r = (uint64_t)arc4random(); - r <<= 32; - r |= arc4random(); - rnd->dp[i] = (r & MP_MASK); - } - if (top == 0) { - rnd->dp[rnd->used - 1] |= (((mp_digit)1)<<((mp_digit)DIGIT_BIT)); - } - if (top == 1) { - rnd->dp[rnd->used - 1] |= (((mp_digit)1)<<((mp_digit)DIGIT_BIT)); - rnd->dp[rnd->used - 1] |= (((mp_digit)1)<<((mp_digit)(DIGIT_BIT - 1))); - } - if (bottom) { - rnd->dp[0] |= 0x1; - } - return 1; -} - -int -BN_rand_range(BIGNUM *rnd, BIGNUM *range) -{ - if (rnd == NULL || range == NULL || BN_is_zero(range)) { - return 0; - } - BN_rand(rnd, BN_num_bits(range), 1, 0); - return mp_mod(rnd, range, rnd) == MP_OKAY; -} - -int -BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int, int, void *), BN_CTX *ctx, void *cb_arg) -{ - int primality; - - if (a == NULL) { - return 0; - } - USE_ARG(ctx); - USE_ARG(cb_arg); - USE_ARG(callback); - return (mp_prime_is_prime(__UNCONST(a), checks, &primality) == MP_OKAY) ? primality : 0; -} - -const BIGNUM * -BN_value_one(void) -{ - static mp_digit digit = 1UL; - static const BIGNUM one = { &digit, 1, 1, 0 }; - - return &one; -} - -int -BN_hex2bn(BIGNUM **a, const char *str) -{ - return getbn(a, str, 16); -} - -int -BN_dec2bn(BIGNUM **a, const char *str) -{ - return getbn(a, str, 10); -} - -int -BN_mod_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) -{ - USE_ARG(ctx); - if (r == NULL || a == NULL || b == NULL || m == NULL) { - return 0; - } - return mp_submod(a, b, __UNCONST(m), r) == MP_OKAY; -} - -int -BN_is_bit_set(const BIGNUM *a, int n) -{ - if (a == NULL || n < 0 || n >= a->used * DIGIT_BIT) { - return 0; - } - return (a->dp[n / DIGIT_BIT] & (1 << (n % DIGIT_BIT))) ? 1 : 0; -} diff --git a/security/libnetpgpverify/files/src/libbn/bn.h b/security/libnetpgpverify/files/src/libbn/bn.h deleted file mode 100644 index fdc49d8760a..00000000000 --- a/security/libnetpgpverify/files/src/libbn/bn.h +++ /dev/null @@ -1,146 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef FAUXBN_H_ -#define FAUXBN_H_ 20100108 - -#include <sys/types.h> - -#ifndef _KERNEL -# include <inttypes.h> -# include <stdio.h> -#endif - -#ifndef __BEGIN_DECLS -# if defined(__cplusplus) -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -# else -# define __BEGIN_DECLS -# define __END_DECLS -# endif -#endif - -__BEGIN_DECLS - -/* should be 32bit on ILP32, 64bit on LP64 */ -typedef unsigned long mp_digit; -typedef uint64_t mp_word; - -/* multi-precision integer */ -typedef struct mp_int { - mp_digit *dp; /* array of digits */ - int used; /* # of digits used */ - int alloc; /* # of digits allocated */ - int sign; /* non-zero if negative */ -} mp_int; - -#define BIGNUM mp_int -#define BN_ULONG mp_digit - -/* a "context" of mp integers - never really used */ -typedef struct bn_ctx_t { - size_t count; - size_t arraysize; - BIGNUM **v; -} BN_CTX; - -#define MP_LT -1 -#define MP_EQ 0 -#define MP_GT 1 - -#define MP_ZPOS 0 -#define MP_NEG 1 - -#define MP_OKAY 0 -#define MP_MEM -2 -#define MP_VAL -3 -#define MP_RANGE MP_VAL - -/*********************************/ - -#define BN_is_negative(x) ((x)->sign == MP_NEG) -#define BN_is_zero(a) (((a)->used == 0) ? 1 : 0) -#define BN_is_odd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? 1 : 0) -#define BN_is_even(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? 1 : 0) - -BIGNUM *BN_new(void); -BIGNUM *BN_dup(const BIGNUM */*a*/); -int BN_copy(BIGNUM */*b*/, const BIGNUM */*a*/); - -void BN_init(BIGNUM */*a*/); -void BN_free(BIGNUM */*a*/); -void BN_clear(BIGNUM */*a*/); -void BN_clear_free(BIGNUM */*a*/); - -int BN_cmp(BIGNUM */*a*/, BIGNUM */*b*/); - -BIGNUM *BN_bin2bn(const uint8_t */*buf*/, int /*size*/, BIGNUM */*bn*/); -int BN_bn2bin(const BIGNUM */*a*/, unsigned char */*b*/); -char *BN_bn2hex(const BIGNUM */*a*/); -char *BN_bn2dec(const BIGNUM */*a*/); -int BN_hex2bn(BIGNUM **/*a*/, const char */*str*/); -int BN_dec2bn(BIGNUM **/*a*/, const char */*str*/); -#ifndef _KERNEL -int BN_print_fp(FILE */*fp*/, const BIGNUM */*a*/); -#endif - -int BN_add(BIGNUM */*r*/, const BIGNUM */*a*/, const BIGNUM */*b*/); -int BN_sub(BIGNUM */*r*/, const BIGNUM */*a*/, const BIGNUM */*b*/); -int BN_mul(BIGNUM */*r*/, const BIGNUM */*a*/, const BIGNUM */*b*/, BN_CTX */*ctx*/); -int BN_div(BIGNUM */*q*/, BIGNUM */*r*/, const BIGNUM */*a*/, const BIGNUM */*b*/, BN_CTX */*ctx*/); -void BN_swap(BIGNUM */*a*/, BIGNUM */*b*/); -int BN_lshift(BIGNUM */*r*/, const BIGNUM */*a*/, int /*n*/); -int BN_lshift1(BIGNUM */*r*/, BIGNUM */*a*/); -int BN_rshift(BIGNUM */*r*/, const BIGNUM */*a*/, int /*n*/); -int BN_rshift1(BIGNUM */*r*/, BIGNUM */*a*/); -int BN_set_word(BIGNUM */*a*/, BN_ULONG /*w*/); -void BN_set_negative(BIGNUM */*a*/, int /*n*/); - -int BN_num_bytes(const BIGNUM */*a*/); -int BN_num_bits(const BIGNUM */*a*/); - -int BN_mod_exp(BIGNUM */*r*/, BIGNUM */*a*/, BIGNUM */*p*/, BIGNUM */*m*/, BN_CTX */*ctx*/); -BIGNUM *BN_mod_inverse(BIGNUM */*ret*/, BIGNUM */*a*/, const BIGNUM */*n*/, BN_CTX */*ctx*/); -int BN_mod_mul(BIGNUM */*ret*/, BIGNUM */*a*/, BIGNUM */*b*/, const BIGNUM */*m*/, BN_CTX */*ctx*/); -int BN_mod_sub(BIGNUM */*r*/, BIGNUM */*a*/, BIGNUM */*b*/, const BIGNUM */*m*/, BN_CTX */*ctx*/); - -BN_CTX *BN_CTX_new(void); -BIGNUM *BN_CTX_get(BN_CTX */*ctx*/); -void BN_CTX_start(BN_CTX */*ctx*/); -void BN_CTX_end(BN_CTX */*ctx*/); -void BN_CTX_init(BN_CTX */*c*/); -void BN_CTX_free(BN_CTX */*c*/); - -int BN_rand(BIGNUM */*rnd*/, int /*bits*/, int /*top*/, int /*bottom*/); -int BN_rand_range(BIGNUM */*rnd*/, BIGNUM */*range*/); - -int BN_is_prime(const BIGNUM */*a*/, int /*checks*/, void (*callback)(int, int, void *), BN_CTX */*ctx*/, void */*cb_arg*/); - -const BIGNUM *BN_value_one(void); -int BN_is_bit_set(const BIGNUM */*a*/, int /*n*/); - -__END_DECLS - -#endif diff --git a/security/libnetpgpverify/files/src/libbn/libnetpgpbn.3 b/security/libnetpgpverify/files/src/libbn/libnetpgpbn.3 deleted file mode 100644 index 3428ce11a9a..00000000000 --- a/security/libnetpgpverify/files/src/libbn/libnetpgpbn.3 +++ /dev/null @@ -1,304 +0,0 @@ -.\" $NetBSD: libnetpgpbn.3,v 1.2 2013/07/20 21:50:54 wiz Exp $ -.\" -.\" Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org> -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.Dd April 13, 2012 -.Dt LIBNETPGPBN 3 -.Os -.Sh NAME -.Nm libnetpgpbn -.Nd BIGNUM library of multi-precision integers -.Sh LIBRARY -.Lb libnetpgpbn -.Sh SYNOPSIS -.In netpgp/bn.h -.Ft BIGNUM * -.Fo BN_new -.Fa "void" -.Fc -.Ft BIGNUM * -.Fo BN_dup -.Fa "const BIGNUM *orig" -.Fc -.Ft int -.Fo BN_copy -.Fa "BIGNUM *to" "const BIGNUM *from" -.Fc -.Ft void -.Fo BN_swap -.Fa "BIGNUM *a" "BIGNUM *b" -.Fc -.Pp -.Ft void -.Fo BN_init -.Fa "BIGNUM *bn" -.Fc -.Ft void -.Fo BN_free -.Fa "BIGNUM *bn" -.Fc -.Ft void -.Fo BN_clear -.Fa "BIGNUM *bn" -.Fc -.Ft void -.Fo BN_clear_free -.Fa "BIGNUM *bn" -.Fc -.Pp -.Ft void -.Fo BN_clear_free -.Fa "BIGNUM *bn" -.Fc -.Pp -.Ft int -.Fo BN_cmp -.Fa "BIGNUM *lhs" "BIGNUM *rhs" -.Fc -.Ft int -.Fo BN_is_negative -.Fa "BIGNUM *bn" -.Fc -.Ft int -.Fo BN_is_zero -.Fa "BIGNUM *bn" -.Fc -.Ft int -.Fo BN_is_odd -.Fa "BIGNUM *bn" -.Fc -.Ft int -.Fo BN_is_even -.Fa "BIGNUM *bn" -.Fc -.Pp -.Ft BIGNUM * -.Fo BN_bin2bn -.Fa "const uint8_t *buf" "int size" "BIGNUM *bn" -.Fc -.Ft int -.Fo BN_bn2bin -.Fa "BIGNUM *bn" "uint8_t *buf" -.Fc -.Ft int -.Fo BN_bn2bin -.Fa "BIGNUM *bn" "uint8_t *buf" -.Fc -.Ft char * -.Fo BN_bn2hex -.Fa "const BIGNUM *bn" -.Fc -.Ft char * -.Fo BN_bn2dec -.Fa "const BIGNUM *bn" -.Fc -.Ft int -.Fo BN_hex2bn -.Fa "BIGNUM **bn" "const char *str" -.Fc -.Ft int -.Fo BN_dec2bn -.Fa "BIGNUM **bn" "const char *str" -.Fc -.Ft int -.Fo BN_print_fp -.Fa "FILE *fp" "const BIGNUM *bn" -.Fc -.Pp -.Ft int -.Fo BN_add -.Fa "BIGNUM *sum" "const BIGNUM *a" "const BIGNUM *b" -.Fc -.Ft int -.Fo BN_sub -.Fa "BIGNUM *sum" "const BIGNUM *a" "const BIGNUM *b" -.Fc -.Ft int -.Fo BN_mul -.Fa "BIGNUM *product" "const BIGNUM *a" "const BIGNUM *b" "BN_CTX *context" -.Fc -.Ft int -.Fo BN_div -.Fa "BIGNUM *quotient" "BIGNUM *remainder" "const BIGNUM *a" "const BIGNUM *b" "BN_CTX *context" -.Fc -.Pp -.Ft int -.Fo BN_lshift -.Fa "BIGNUM *result" "const BIGNUM *bn" "int n" -.Fc -.Ft int -.Fo BN_lshift1 -.Fa "BIGNUM *result" "const BIGNUM *bn" -.Fc -.Ft int -.Fo BN_rshift -.Fa "BIGNUM *result" "const BIGNUM *bn" "int n" -.Fc -.Ft int -.Fo BN_rshift1 -.Fa "BIGNUM *result" "const BIGNUM *bn" -.Fc -.Pp -.Ft int -.Fo BN_set_word -.Fa "BIGNUM *result" "unsigned long val" -.Fc -.Ft int -.Fo BN_set_negative -.Fa "BIGNUM *result" "int val" -.Fc -.Pp -.Ft int -.Fo BN_num_bytes -.Fa "const BIGNUM *bn" -.Fc -.Ft int -.Fo BN_num_bits -.Fa "const BIGNUM *bn" -.Fc -.Pp -.Ft int -.Fo BN_mod_exp -.Fa "BIGNUM *result" "BIGNUM *a" "BIGNUM *p" "BIGNUM *m" "BN_CTX *context" -.Fc -.Ft BIGNUM * -.Fo BN_mod_inverse -.Fa "BIGNUM *result" "BIGNUM *a" "BIGNUM *n" "BN_CTX *context" -.Fc -.Ft int -.Fo BN_mod_mul -.Fa "BIGNUM *result" "BIGNUM *a" "BIGNUM *b" "BIGNUM *m" "BN_CTX *context" -.Fc -.Ft int -.Fo BN_mod_sub -.Fa "BIGNUM *result" "BIGNUM *a" "BIGNUM *b" "BIGNUM *m" "BN_CTX *context" -.Fc -.Pp -.Ft BN_CTX * -.Fo BN_CTX_new -.Fa "void" -.Fc -.Ft BIGNUM * -.Fo BN_CTX_get -.Fa "BN_CTX *context" -.Fc -.Ft void -.Fo BN_CTX_start -.Fa "BN_CTX *context" -.Fc -.Ft void -.Fo BN_CTX_end -.Fa "BN_CTX *context" -.Fc -.Ft void -.Fo BN_CTX_init -.Fa "BN_CTX *context" -.Fc -.Ft void -.Fo BN_CTX_free -.Fa "BN_CTX *context" -.Fc -.Ft int -.Fo BN_rand -.Fa "BIGNUM *result" "int bits" "int top" "int bottom" -.Fc -.Ft int -.Fo BN_rand_range -.Fa "BIGNUM *result" "BIGNUM *range" -.Fc -.Ft int -.Fo BN_is_prime -.Fa "const BIGNUM *bn" "int checks" "void (*callback)(int int void)" -.Fa "BN_CTX *context" "void *callbackarg" -.Fc -.Pp -.Ft const BIGNUM * -.Fo BN_value_one -.Fa "void" -.Fc -.Ft int -.Fo BN_is_bit_set -.Fa "const BIGNUM *bn" "int n" -.Fc -.Sh DESCRIPTION -.Nm -emulates the API of the openssl -.Xr bn 3 -library. -It is implemented using Tom St Denis -.Dq libtommath -library. -.Sh EXAMPLES -The follow code fragment will make a JSON object -out of the string -.Dq Hello <USERNAME>\en -in the -buffer called -.Dq buf -where -.Dq USERNAME -is the name of the user taken from the runtime environment. -The encoded text will be in an allocated buffer called -.Dq s -.Bd -literal -offset indent -mj_t atom; -char buf[BUFSIZ]; -char *s; -int cc; - -(void) memset(\*[Am]atom, 0x0, sizeof(atom)); -cc = snprintf(buf, sizeof(buf), "Hello %s\en", getenv("USER")); -mj_create(\*[Am]atom, "string", buf, cc); -cc = mj_asprint(\*[Am]s, \*[Am]atom, MJ_JSON_ENCODE); -.Ed -.Pp -and the following example will take the (binary) text which has been encoded into -JSON and is in the buffer -.Dq buf , -such as in the previous example, and re-create the original text: -.Bd -literal -offset indent -int from, to, tok, cc; -char *s; -mj_t atom; - -(void) memset(\*[Am]atom, 0x0, sizeof(atom)); -from = to = tok = 0; -mj_parse(\*[Am]atom, buf, \*[Am]from, \*[Am]to, \*[Am]tok); -cc = mj_asprint(\*[Am]s, \*[Am]atom, MJ_HUMAN); -printf("%.*s", cc, s); -.Ed -.Pp -The -.Dv s -pointer points to allocated storage with the original NUL-terminated string -in it. -.Sh SEE ALSO -.Xr bn 3 -.Sh HISTORY -The -.Nm -library first appeared in -.Nx 7.0 . -.Sh AUTHORS -.An Alistair Crooks Aq Mt agc@NetBSD.org diff --git a/security/libnetpgpverify/files/src/libbn/misc.c b/security/libnetpgpverify/files/src/libbn/misc.c deleted file mode 100644 index b3bb5ea68f8..00000000000 --- a/security/libnetpgpverify/files/src/libbn/misc.c +++ /dev/null @@ -1,82 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/syslog.h> - -#ifdef _KERNEL -# include <sys/kmem.h> -#else -# include <ctype.h> -# include <inttypes.h> -# include <stdarg.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# include <time.h> -# include <unistd.h> -#endif - -#include "misc.h" - -#ifndef USE_ARG -#define USE_ARG(x) /*LINTED*/(void)&(x) -#endif - -void * -netpgp_allocate(size_t n, size_t nels) -{ -#ifdef _KERNEL - return kmem_zalloc(n * nels, KM_SLEEP); -#else - return calloc(n, nels); -#endif -} - -void -netpgp_deallocate(void *ptr, size_t size) -{ -#ifdef _KERNEL - kmem_free(ptr, size); -#else - USE_ARG(size); - free(ptr); -#endif -} - -#ifndef _KERNEL -void -logmessage(const int level, const char *fmt, ...) -{ - va_list args; - - USE_ARG(level); - if (fmt != NULL) { - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - } -} -#endif diff --git a/security/libnetpgpverify/files/src/libbn/misc.h b/security/libnetpgpverify/files/src/libbn/misc.h deleted file mode 100644 index dbace86fdcf..00000000000 --- a/security/libnetpgpverify/files/src/libbn/misc.h +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef MISC_H_ -#define MISC_H_ 20110705 - -#include <sys/types.h> - -#include <inttypes.h> - -#ifndef __BEGIN_DECLS -# if defined(__cplusplus) -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -# else -# define __BEGIN_DECLS -# define __END_DECLS -# endif -#endif - -__BEGIN_DECLS - -void *netpgp_allocate(size_t /*n*/, size_t /*nels*/); -void netpgp_deallocate(void */*ptr*/, size_t /*size*/); - -#ifndef _KERNEL -void logmessage(const int /*level*/, const char */*fmt*/, ...); -#endif - -__END_DECLS - -#endif diff --git a/security/libnetpgpverify/files/src/libbn/rand.c b/security/libnetpgpverify/files/src/libbn/rand.c deleted file mode 100644 index d2bcc1196e6..00000000000 --- a/security/libnetpgpverify/files/src/libbn/rand.c +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include <sys/types.h> -#include <sys/param.h> - -#ifdef _KERNEL -# include <sys/kmem.h> -#else -# include <arpa/inet.h> -# include <ctype.h> -# include <inttypes.h> -# include <stdarg.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# include <time.h> -# include <unistd.h> -#endif - -#include "rand.h" - -int -RAND_bytes(unsigned char *buf, int num) -{ - uint32_t r; - size_t cc; - int i; - - if (buf == NULL || num < 0) { - return 0; - } - for (i = 0 ; i < num ; i += sizeof(r)) { - r = arc4random(); - cc = MIN(sizeof(r), (size_t)(num - i)); - (void) memcpy(&buf[i], &r, cc); - } - return 1; -} diff --git a/security/libnetpgpverify/files/src/libbn/rand.h b/security/libnetpgpverify/files/src/libbn/rand.h deleted file mode 100644 index c2bdc950149..00000000000 --- a/security/libnetpgpverify/files/src/libbn/rand.h +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef RAND_H_ -#define RAND_H_ 20120327 - -#ifndef __BEGIN_DECLS -# if defined(__cplusplus) -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -# else -# define __BEGIN_DECLS -# define __END_DECLS -# endif -#endif - -__BEGIN_DECLS - -int RAND_bytes(unsigned char */*buf*/, int /*len*/); - -__END_DECLS - -#endif diff --git a/security/libnetpgpverify/files/src/libbn/stubs.c b/security/libnetpgpverify/files/src/libbn/stubs.c deleted file mode 100644 index 5e78fab880b..00000000000 --- a/security/libnetpgpverify/files/src/libbn/stubs.c +++ /dev/null @@ -1,217 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include <sys/types.h> -#include <sys/param.h> - -#ifdef _KERNEL -# include <sys/kmem.h> -#else -# include <arpa/inet.h> -# include <ctype.h> -# include <inttypes.h> -# include <stdarg.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# include <time.h> -# include <unistd.h> -#endif - -#include "misc.h" -#include "bn.h" - -#include "stubs.h" - -#ifndef USE_ARG -#define USE_ARG(x) /*LINTED*/(void)&(x) -#endif - -void -OpenSSL_add_all_algorithms(void) -{ -} - -void -OPENSSL_add_all_algorithms_noconf(void) -{ -} - -void -CRYPTO_cleanup_all_ex_data(void) -{ -} - -BIO * -BIO_new_fd(int fd, int close_flag) -{ - USE_ARG(fd); - USE_ARG(close_flag); - return NULL; -} - -unsigned long -ERR_get_error(void) -{ - return 0; -} - -char * -ERR_error_string(unsigned long e, char *buf) -{ - static char staticbuf[120]; - - if (buf == NULL) { - buf = staticbuf; - } - snprintf(buf, 120, "error:%lu:netssl:[unknown function]:[unknown error]", e); - return buf; -} - -void -ERR_remove_state(unsigned long pid) -{ - USE_ARG(pid); -} - -void -ERR_print_errors(BIO *bp) -{ - USE_ARG(bp); -} - -void -idea_set_encrypt_key(uint8_t *key, IDEA_KEY_SCHEDULE *ks) -{ - printf("idea_set_encrypt_key stubbed\n"); - USE_ARG(key); - USE_ARG(ks); -} - -void -idea_set_decrypt_key(IDEA_KEY_SCHEDULE *encrypt_ks, IDEA_KEY_SCHEDULE *decrypt_ks) -{ - printf("idea_set_decrypt_key stubbed\n"); - USE_ARG(encrypt_ks); - USE_ARG(decrypt_ks); -} - -void -idea_cfb64_encrypt(uint8_t *in, uint8_t *out, long length, des_key_schedule *ks, des_cblock *ivec, int *num, int enc) -{ - printf("idea_cfb64_encrypt stubbed\n"); - USE_ARG(in); - USE_ARG(out); - USE_ARG(length); - USE_ARG(ks); - USE_ARG(ivec); - USE_ARG(num); - USE_ARG(enc); -} - -void -idea_ecb_encrypt(uint8_t *in, uint8_t *out, IDEA_KEY_SCHEDULE *ks) -{ - printf("idea_cfb64_decrypt stubbed\n"); - USE_ARG(in); - USE_ARG(out); - USE_ARG(ks); -} - -int -Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key) -{ - printf("Camellia_set_key stubbed\n"); - USE_ARG(userKey); - USE_ARG(bits); - USE_ARG(key); - return 0; -} - -void -Camellia_encrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key) -{ - printf("Camellia_encrypt stubbed\n"); - USE_ARG(in); - USE_ARG(out); - USE_ARG(key); -} - -void -Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc) -{ - printf("Camellia_cfb128_encrypt stubbed\n"); - USE_ARG(in); - USE_ARG(out); - USE_ARG(length); - USE_ARG(key); - USE_ARG(ivec); - USE_ARG(num); - USE_ARG(enc); -} - -void -Camellia_decrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key) -{ - printf("Camellia_decrypt stubbed\n"); - USE_ARG(in); - USE_ARG(out); - USE_ARG(key); -} - -int -DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule) -{ - printf("DES_set_key stubbed\n"); - USE_ARG(key); - USE_ARG(schedule); - return 0; -} - -void -DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, DES_key_schedule *ks1,DES_key_schedule *ks2, DES_key_schedule *ks3, int enc) -{ - printf("DES_ecb3_encrypt stubbed\n"); - USE_ARG(input); - USE_ARG(output); - USE_ARG(ks1); - USE_ARG(ks2); - USE_ARG(ks3); - USE_ARG(enc); -} - -void -DES_ede3_cfb64_encrypt(const unsigned char *in,unsigned char *out, long length,DES_key_schedule *ks1, DES_key_schedule *ks2,DES_key_schedule *ks3, DES_cblock *ivec,int *num,int enc) -{ - printf("DES_ede3_cfb64_encrypt stubbed\n"); - USE_ARG(in); - USE_ARG(out); - USE_ARG(length); - USE_ARG(ks1); - USE_ARG(ks2); - USE_ARG(ks3); - USE_ARG(ivec); - USE_ARG(num); - USE_ARG(enc); -} diff --git a/security/libnetpgpverify/files/src/libbn/stubs.h b/security/libnetpgpverify/files/src/libbn/stubs.h deleted file mode 100644 index 6441b22606c..00000000000 --- a/security/libnetpgpverify/files/src/libbn/stubs.h +++ /dev/null @@ -1,94 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef STUBS_H_ -#define STUBS_H_ 20120327 - -#ifndef __BEGIN_DECLS -# if defined(__cplusplus) -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -# else -# define __BEGIN_DECLS -# define __END_DECLS -# endif -#endif - -__BEGIN_DECLS - -/*********************************/ -/* stubs */ -/*********************************/ - -void OpenSSL_add_all_algorithms(void); -void OPENSSL_add_all_algorithms_noconf(void); -void CRYPTO_cleanup_all_ex_data(void); - -#include <stdio.h> - -#define BIO FILE - -BIO *BIO_new_fd(int /*fd*/, int /*close_flag*/); - -unsigned long ERR_get_error(void); -char *ERR_error_string(unsigned long /*e*/, char */*buf*/); -void ERR_remove_state(unsigned long /*pid*/); -void ERR_print_errors(BIO */*bp*/); - -#define IDEA_KEY_SCHEDULE void -#define des_key_schedule void -#define des_cblock void -#define IDEA_DECRYPT 0 -#define IDEA_ENCRYPT 1 -#define IDEA_BLOCK 8 -#define IDEA_KEY_LENGTH 16 - -void idea_set_encrypt_key(uint8_t *key, IDEA_KEY_SCHEDULE *ks); -void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *encrypt_ks, IDEA_KEY_SCHEDULE *decrypt_ks); -void idea_cfb64_encrypt(uint8_t *in, uint8_t *out, long length, des_key_schedule *ks, des_cblock *ivec, int *num, int enc); -void idea_ecb_encrypt(uint8_t *in, uint8_t *out, IDEA_KEY_SCHEDULE *ks); - -#define CAMELLIA_KEY void -#define CAMELLIA_DECRYPT 0 -#define CAMELLIA_ENCRYPT 1 -#define CAMELLIA_BLOCK_SIZE 16 - -int Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key); -void Camellia_encrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key); -void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const CAMELLIA_KEY *key, unsigned char *ivec, int *num, const int enc); -void Camellia_decrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key); - -#define const_DES_cblock void -#define DES_cblock void -#define DES_key_schedule void -#define DES_DECRYPT 0 -#define DES_ENCRYPT 1 - -int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule); -void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, DES_key_schedule *ks1,DES_key_schedule *ks2, DES_key_schedule *ks3, int enc); -void DES_ede3_cfb64_encrypt(const unsigned char *in,unsigned char *out, long length,DES_key_schedule *ks1, DES_key_schedule *ks2,DES_key_schedule *ks3, DES_cblock *ivec,int *num,int enc); - -__END_DECLS - -#endif diff --git a/security/libnetpgpverify/files/src/libdigest/Makefile b/security/libnetpgpverify/files/src/libdigest/Makefile deleted file mode 100644 index 4226113735f..00000000000 --- a/security/libnetpgpverify/files/src/libdigest/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -LIB=netdigest -SRCS= tiger.c digest.c -MKMAN=no -WARNS=4 -CPPFLAGS+=-I${EXTDIST} - -INCS=digest.h tiger.h -INCSDIR=/usr/include/netpgp -EXTDIST=${.CURDIR} - -.include <bsd.lib.mk> - -.if ${HAVE_GCC} >= 45 -#COPTS.isns_pdu.c+= -fno-strict-aliasing -CPPFLAGS+= -fno-strict-aliasing -.endif diff --git a/security/libnetpgpverify/files/src/libdigest/digest.c b/security/libnetpgpverify/files/src/libdigest/digest.c deleted file mode 100644 index 8b30da7ebd5..00000000000 --- a/security/libnetpgpverify/files/src/libdigest/digest.c +++ /dev/null @@ -1,383 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <sys/syslog.h> - -#ifdef _KERNEL -# include <sys/md5.h> -# include <sys/sha1.h> -# include <sys/sha2.h> -# include <sys/rmd160.h> -# include <sys/kmem.h> -#else -# include <arpa/inet.h> -# include <ctype.h> -# include <inttypes.h> -# include <md5.h> -# include <rmd160.h> -# include <sha1.h> -# include <sha2.h> -# include <stdarg.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# include <time.h> -# include <unistd.h> -#endif - -#include "digest.h" - -static uint8_t prefix_md5[] = { - 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, - 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 -}; - -static uint8_t prefix_sha1[] = { - 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03, 0x02, - 0x1A, 0x05, 0x00, 0x04, 0x14 -}; - -static uint8_t prefix_sha256[] = { - 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 -}; - -static uint64_t prefix_tiger[] = { - 0x0123456789ABCDEFLL, - 0xFEDCBA9876543210LL, - 0xF096A5B4C3B2E187LL -}; - -static uint8_t prefix_rmd160[] = { - 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, - 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 -}; - -static uint8_t prefix_sha512[] = { - 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 -}; - -#define V4_SIGNATURE 4 - -/*************************************************************************/ - -void -MD5_Init(MD5_CTX *context) -{ - if (context) { - MD5Init(context); - } -} - -void -MD5_Update(MD5_CTX *context, const unsigned char *data, unsigned int len) -{ - if (context && data) { - MD5Update(context, data, len); - } -} - -void -MD5_Final(unsigned char digest[16], MD5_CTX *context) -{ - if (digest && context) { - MD5Final(digest, context); - } -} - -void -SHA1_Init(SHA1_CTX *context) -{ - if (context) { - SHA1Init(context); - } -} - -void -SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len) -{ - if (context && data) { - SHA1Update(context, data, len); - } -} - -void -SHA1_Final(unsigned char digest[20], SHA1_CTX *context) -{ - if (digest && context) { - SHA1Final(digest, context); - } -} - -void -RMD160_Init(RMD160_CTX *context) -{ - if (context) { - RMD160Init(context); - } -} - -void -RMD160_Update(RMD160_CTX *context, const unsigned char *data, unsigned int len) -{ - if (context && data) { - RMD160Update(context, data, len); - } -} - -void -RMD160_Final(unsigned char digest[20], RMD160_CTX *context) -{ - if (context && digest) { - RMD160Final(digest, context); - } -} - - -/* algorithm size (raw) */ -int -digest_alg_size(unsigned alg) -{ - switch(alg) { - case MD5_HASH_ALG: - return 16; - case SHA1_HASH_ALG: - return 20; - case RIPEMD_HASH_ALG: - return RMD160_DIGEST_LENGTH; - case SHA256_HASH_ALG: - return 32; - case SHA512_HASH_ALG: - return 64; - case TIGER_HASH_ALG: - case TIGER2_HASH_ALG: - return TIGER_DIGEST_LENGTH; - default: - printf("hash_any: bad algorithm\n"); - return 0; - } -} - -/* initialise the hash structure */ -int -digest_init(digest_t *hash, const uint32_t hashalg) -{ - if (hash == NULL) { - return 0; - } - switch(hash->alg = hashalg) { - case MD5_HASH_ALG: - MD5Init(&hash->u.md5ctx); - hash->size = 16; - hash->prefix = prefix_md5; - hash->len = sizeof(prefix_md5); - hash->ctx = &hash->u.md5ctx; - return 1; - case SHA1_HASH_ALG: - SHA1Init(&hash->u.sha1ctx); - hash->size = 20; - hash->prefix = prefix_sha1; - hash->len = sizeof(prefix_sha1); - hash->ctx = &hash->u.sha1ctx; - return 1; - case RIPEMD_HASH_ALG: - RMD160Init(&hash->u.rmd160ctx); - hash->size = 20; - hash->prefix = prefix_rmd160; - hash->len = sizeof(prefix_rmd160); - hash->ctx = &hash->u.rmd160ctx; - return 1; - case SHA256_HASH_ALG: - SHA256_Init(&hash->u.sha256ctx); - hash->size = 32; - hash->prefix = prefix_sha256; - hash->len = sizeof(prefix_sha256); - hash->ctx = &hash->u.sha256ctx; - return 1; - case SHA512_HASH_ALG: - SHA512_Init(&hash->u.sha512ctx); - hash->size = 64; - hash->prefix = prefix_sha512; - hash->len = sizeof(prefix_sha512); - hash->ctx = &hash->u.sha512ctx; - return 1; - case TIGER_HASH_ALG: - TIGER_Init(&hash->u.tigerctx); - hash->size = TIGER_DIGEST_LENGTH; - hash->prefix = prefix_tiger; - hash->len = sizeof(prefix_tiger); - hash->ctx = &hash->u.tigerctx; - return 1; - case TIGER2_HASH_ALG: - TIGER2_Init(&hash->u.tigerctx); - hash->size = TIGER_DIGEST_LENGTH; - hash->prefix = prefix_tiger; - hash->len = sizeof(prefix_tiger); - hash->ctx = &hash->u.tigerctx; - return 1; - default: - printf("hash_any: bad algorithm\n"); - return 0; - } -} - -typedef struct rec_t { - const char *s; - const unsigned alg; -} rec_t; - -static rec_t hashalgs[] = { - { "md5", MD5_HASH_ALG }, - { "sha1", SHA1_HASH_ALG }, - { "ripemd", RIPEMD_HASH_ALG }, - { "sha256", SHA256_HASH_ALG }, - { "sha512", SHA512_HASH_ALG }, - { "tiger", TIGER_HASH_ALG }, - { "tiger2", TIGER2_HASH_ALG }, - { NULL, 0 } -}; - -/* initialise by string alg name */ -unsigned -digest_get_alg(const char *hashalg) -{ - rec_t *r; - - for (r = hashalgs ; hashalg && r->s ; r++) { - if (strcasecmp(r->s, hashalg) == 0) { - return r->alg; - } - } - return 0; -} - -int -digest_update(digest_t *hash, const uint8_t *data, size_t length) -{ - if (hash == NULL || data == NULL) { - return 0; - } - switch(hash->alg) { - case MD5_HASH_ALG: - MD5Update(hash->ctx, data, (unsigned)length); - return 1; - case SHA1_HASH_ALG: - SHA1Update(hash->ctx, data, (unsigned)length); - return 1; - case RIPEMD_HASH_ALG: - RMD160Update(hash->ctx, data, (unsigned)length); - return 1; - case SHA256_HASH_ALG: - SHA256_Update(hash->ctx, data, length); - return 1; - case SHA512_HASH_ALG: - SHA512_Update(hash->ctx, data, length); - return 1; - case TIGER_HASH_ALG: - case TIGER2_HASH_ALG: - TIGER_Update(hash->ctx, data, length); - return 1; - default: - printf("hash_any: bad algorithm\n"); - return 0; - } -} - -unsigned -digest_final(uint8_t *out, digest_t *hash) -{ - if (hash == NULL || out == NULL) { - return 0; - } - switch(hash->alg) { - case MD5_HASH_ALG: - MD5Final(out, hash->ctx); - break; - case SHA1_HASH_ALG: - SHA1Final(out, hash->ctx); - break; - case RIPEMD_HASH_ALG: - RMD160Final(out, hash->ctx); - break; - case SHA256_HASH_ALG: - SHA256_Final(out, hash->ctx); - break; - case SHA512_HASH_ALG: - SHA512_Final(out, hash->ctx); - break; - case TIGER_HASH_ALG: - TIGER_Final(out, hash->ctx); - break; - default: - printf("hash_any: bad algorithm\n"); - return 0; - } - (void) memset(hash->ctx, 0x0, hash->size); - return (unsigned)hash->size; -} - -int -digest_length(digest_t *hash, unsigned hashedlen) -{ - uint8_t trailer[6]; - - if (hash == NULL) { - return 0; - } - trailer[0] = V4_SIGNATURE; - trailer[1] = 0xFF; - trailer[2] = (uint8_t)((hashedlen >> 24) & 0xff); - trailer[3] = (uint8_t)((hashedlen >> 16) & 0xff); - trailer[4] = (uint8_t)((hashedlen >> 8) & 0xff); - trailer[5] = (uint8_t)(hashedlen & 0xff); - digest_update(hash, trailer, sizeof(trailer)); - return 1; -} - -unsigned -digest_get_prefix(unsigned hashalg, uint8_t *prefix, size_t size) -{ - if (prefix == NULL) { - return 0; - } - switch (hashalg) { - case MD5_HASH_ALG: - memcpy(prefix, prefix_md5, sizeof(prefix_md5)); - return sizeof(prefix_md5); - case SHA1_HASH_ALG: - memcpy(prefix, prefix_sha1, sizeof(prefix_sha1)); - return sizeof(prefix_sha1); - case SHA256_HASH_ALG: - memcpy(prefix, prefix_sha256, sizeof(prefix_sha256)); - return sizeof(prefix_sha256); - default: - printf("digest_get_prefix: unknown hash algorithm: %d\n", hashalg); - return 0; - } -} - diff --git a/security/libnetpgpverify/files/src/libdigest/digest.h b/security/libnetpgpverify/files/src/libdigest/digest.h deleted file mode 100644 index 28d1ebd08be..00000000000 --- a/security/libnetpgpverify/files/src/libdigest/digest.h +++ /dev/null @@ -1,109 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef DIGEST_H_ -#define DIGEST_H_ 20100108 - -#include <sys/types.h> - -#ifdef _KERNEL -# include <sys/md5.h> -# include <sys/sha1.h> -# include <sys/sha2.h> -# include <sys/rmd160.h> -#else -# include <md5.h> -# include <sha1.h> -# include <sha2.h> -# include <rmd160.h> -# include <inttypes.h> -#endif - -#include "tiger.h" - -#ifndef __BEGIN_DECLS -# if defined(__cplusplus) -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -# else -# define __BEGIN_DECLS -# define __END_DECLS -# endif -#endif - -__BEGIN_DECLS - -#define MD5_HASH_ALG 1 -#define SHA1_HASH_ALG 2 -#define RIPEMD_HASH_ALG 3 -#define TIGER_HASH_ALG 6 /* from rfc2440 */ -#define SHA256_HASH_ALG 8 -#define SHA384_HASH_ALG 9 -#define SHA512_HASH_ALG 10 -#define SHA224_HASH_ALG 11 -#define TIGER2_HASH_ALG 100 /* private/experimental from rfc4880 */ - -/* structure to describe digest methods */ -typedef struct digest_t { - uint32_t alg; /* algorithm */ - size_t size; /* size */ - union { - MD5_CTX md5ctx; /* MD5 */ - SHA1_CTX sha1ctx; /* SHA1 */ - RMD160_CTX rmd160ctx; /* RIPEMD */ - SHA256_CTX sha256ctx; /* SHA256 */ - SHA512_CTX sha512ctx; /* SHA512 */ - TIGER_CTX tigerctx; /* TIGER/TIGER2 */ - } u; - void *prefix; /* points to specific prefix */ - uint32_t len; /* prefix length */ - void *ctx; /* pointer to context array */ -} digest_t; - -unsigned digest_get_alg(const char */*hashalg*/); - -int digest_init(digest_t */*digest*/, const uint32_t /*hashalg*/); - -int digest_update(digest_t */*digest*/, const uint8_t */*data*/, size_t /*size*/); -unsigned digest_final(uint8_t */*out*/, digest_t */*digest*/); -int digest_alg_size(unsigned /*alg*/); -int digest_length(digest_t */*hash*/, unsigned /*hashedlen*/); - -void MD5_Init(MD5_CTX */*context*/); -void MD5_Update(MD5_CTX */*context*/, const unsigned char */*data*/, unsigned int /*len*/); -void MD5_Final(unsigned char /*digest*/[16], MD5_CTX */*context*/); - -void SHA1_Init(SHA1_CTX */*context*/); -void SHA1_Update(SHA1_CTX */*context*/, const unsigned char */*data*/, unsigned int /*len*/); -void SHA1_Final(unsigned char /*digest*/[20], SHA1_CTX */*context*/); - -void RMD160_Init(RMD160_CTX */*ctx*/); -void RMD160_Update(RMD160_CTX */*ctx*/, const unsigned char */*data*/, uint32_t /*len*/); -void RMD160_Final(unsigned char /*digest*/[RMD160_DIGEST_LENGTH], RMD160_CTX */*ctx*/); - -unsigned digest_get_prefix(unsigned /*hashalg*/, uint8_t */*prefix*/, size_t /*size*/); - -__END_DECLS - -#endif diff --git a/security/libnetpgpverify/files/src/libdigest/tiger.3 b/security/libnetpgpverify/files/src/libdigest/tiger.3 deleted file mode 100644 index aea929501f9..00000000000 --- a/security/libnetpgpverify/files/src/libdigest/tiger.3 +++ /dev/null @@ -1,219 +0,0 @@ -.\" $NetBSD: tiger.3,v 1.2 2013/07/20 21:50:54 wiz Exp $ -.\" -.\" Copyright (c) 2011 Alistair Crooks <agc@NetBSD.org> -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.Dd May 30, 2011 -.Dt TIGER 3 -.Os -.Sh NAME -.Nm TIGER_Init , -.Nm TIGER_Update , -.Nm TIGER_Final , -.Nm TIGER_End , -.Nm TIGER_File , -.Nm TIGER_Data -.Nd calculate TIGER message digests -.Sh SYNOPSIS -.In tiger.h -.Ft void -.Fo TIGER_Init -.Fa "TIGER_CTX *context" -.Fc -.Ft void -.Fo TIGER_Update -.Fa "TIGER_CTX *context" "const uint8_t *data" "u_int len" -.Fc -.Ft void -.Fo TIGER_Final -.Fa "uint8_t digest[20]" "TIGER_CTX *context" -.Fc -.Ft "char *" -.Fo TIGER_End -.Fa "TIGER_CTX *context" "char *buf" -.Fc -.Ft "char *" -.Fo TIGER_File -.Fa "char *filename" "char *buf" -.Fc -.Ft "char *" -.Fo TIGER_Data -.Fa "uint8_t *data" "size_t len" "char *buf" -.Fc -.Sh DESCRIPTION -The TIGER functions calculate TIGER message digest functions, -as defined by Ross Anderson and Eli Biham. -The algorithm takes a -message less than 2^64 bits as input and produces a 192-bit digest -suitable for use as a digital signature. -.Pp -At the time of writing, -May 2011, -no attacks or pre-imaging have been discovered against the -.Nm -message digests, whilst the same cannot be said of -.Xr md5 3 -or -.Xr sha1 3 . -.Pp -The -.Fn TIGER_Init -function initializes a TIGER_CTX -.Ar context -for use with -.Fn TIGER_Update , -and -.Fn TIGER_Final . -The -.Fn TIGER_Update -function adds -.Ar data -of length -.Ar len -to the TIGER_CTX specified by -.Ar context . -.Fn TIGER_Final -is called when all data has been added via -.Fn TIGER_Update -and stores a message digest in the -.Ar digest -parameter. -When a -.Dv NULL -pointer is passed to -.Fn TIGER_Final -as first argument only the final padding will be applied and the -current context can still be used with -.Fn TIGER_Update . -.Pp -The core of the TIGER message digest is performed by -.Fn TIGER_Update . -Most programs should use the interface provided by -.Fn TIGER_Init , -.Fn TIGER_Update , -and -.Fn TIGER_Final . -.Pp -The -.Fn TIGER_End -function is a front end for -.Fn TIGER_Final -which converts the digest into an -.Tn ASCII -representation of the 160 bit digest in hexadecimal. -.Pp -The -.Fn TIGER_File -function calculates the digest for a file and returns the result via -.Fn TIGER_End . -If -.Fn TIGER_File -is unable to open the file a -.Dv NULL -pointer is returned. -.Pp -The -.Fn TIGER_Data -function -calculates the digest of an arbitrary string and returns the result via -.Fn TIGER_End . -.Pp -For each of the -.Fn TIGER_End , -.Fn TIGER_File , -and -.Fn TIGER_Data -functions the -.Ar buf -parameter should either be a string of at least 41 characters in -size or a -.Dv NULL -pointer. -In the latter case, space will be dynamically allocated via -.Xr malloc 3 -and should be freed using -.Xr free 3 -when it is no longer needed. -.Sh EXAMPLES -The follow code fragment will calculate the digest for the string -"The quick brown fox jumps over the lazy dog" -which is -.Dq 6d12a41e72e644f017b6f0e2f7b44c6285f06dd5d2c5b075 . -.Bd -literal -offset indent -TIGER_CTX tiger; -uint8_t results[24]; -char *buf; -int n; - -buf = "The quick brown fox jumps over the lazy dog"; -n = strlen(buf); -TIGER_Init(\*[Am]tiger); -TIGER_Update(\*[Am]tiger, (uint8_t *)buf, n); -TIGER_Final(results, \*[Am]tiger); - -/* Print the digest as one long hex value */ -printf("0x"); -for (n = 0; n \*[Lt] 24; n++) - printf("%02x", results[n]); -putchar('\en'); -.Ed -.Pp -Alternately, the helper functions could be used in the following way: -.Bd -literal -offset indent -TIGER_CTX tiger; -uint8_t output[49]; -char *buf = "The quick brown fox jumps over the lazy dog"; - -printf("0x%s", TIGER_Data(buf, strlen(buf), output)); -.Ed -.Sh SEE ALSO -.Xr md5 3 , -.Xr sha1 3 -.Pp -.Rs -.%A Ross Anderson -.%A Eli Biham -.%T "Tiger - A Fast New Hash Function" -.%B Proceedings of Fast Software Encryption 3, Cambridge -.%D 1996 -.Re -.Sh HISTORY -The TIGER functions appeared in -.Nx 6.0 . -.Sh AUTHORS -.An -nosplit -This implementation of TIGER was adapted by -.An Alistair Crooks Aq Mt agc@NetBSD.org -from the original reference code. -.Pp -The -.Fn TIGER_End , -.Fn TIGER_File , -and -.Fn TIGER_Data -helper functions are derived from code written by Poul-Henning Kamp. -.Sh BUGS -All attempts have bene made to optimise for the underlying hardware, -as well as to format the digest properly in an endian-neutral manner. -The author has no VAX hardware on which to test, and so it is not known -whether that platform is supported. diff --git a/security/libnetpgpverify/files/src/libdigest/tiger.c b/security/libnetpgpverify/files/src/libdigest/tiger.c deleted file mode 100644 index e0b44d912e7..00000000000 --- a/security/libnetpgpverify/files/src/libdigest/tiger.c +++ /dev/null @@ -1,906 +0,0 @@ -#include <sys/types.h> - -#include <errno.h> -#include <fcntl.h> -#include <inttypes.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "tiger.h" - -#ifndef IS_LITTLE_ENDIAN -#define IS_LITTLE_ENDIAN(x) (*(char *)(void *)&x) -#define IS_BIG_ENDIAN(x) !(*(char *)(void *)&x) -#endif - -#define BSWAP64(x) ((((x) & 0xffULL) << 56) | \ - (((x) & 0xff00ULL) << 40) | \ - (((x) & 0xff0000ULL) << 24) | \ - (((x) & 0xff000000ULL) << 8) | \ - (((x) & 0xff00000000ULL) >> 8) | \ - (((x) & 0xff0000000000ULL) >> 24) | \ - (((x) & 0xff000000000000ULL) >> 40) | \ - (((x) & 0xff00000000000000ULL) >> 56)) - -/* sboxes.c: Tiger S boxes */ -static uint64_t table[4*256] = { - 0x02AAB17CF7E90C5ELL /* 0 */, 0xAC424B03E243A8ECLL /* 1 */, - 0x72CD5BE30DD5FCD3LL /* 2 */, 0x6D019B93F6F97F3ALL /* 3 */, - 0xCD9978FFD21F9193LL /* 4 */, 0x7573A1C9708029E2LL /* 5 */, - 0xB164326B922A83C3LL /* 6 */, 0x46883EEE04915870LL /* 7 */, - 0xEAACE3057103ECE6LL /* 8 */, 0xC54169B808A3535CLL /* 9 */, - 0x4CE754918DDEC47CLL /* 10 */, 0x0AA2F4DFDC0DF40CLL /* 11 */, - 0x10B76F18A74DBEFALL /* 12 */, 0xC6CCB6235AD1AB6ALL /* 13 */, - 0x13726121572FE2FFLL /* 14 */, 0x1A488C6F199D921ELL /* 15 */, - 0x4BC9F9F4DA0007CALL /* 16 */, 0x26F5E6F6E85241C7LL /* 17 */, - 0x859079DBEA5947B6LL /* 18 */, 0x4F1885C5C99E8C92LL /* 19 */, - 0xD78E761EA96F864BLL /* 20 */, 0x8E36428C52B5C17DLL /* 21 */, - 0x69CF6827373063C1LL /* 22 */, 0xB607C93D9BB4C56ELL /* 23 */, - 0x7D820E760E76B5EALL /* 24 */, 0x645C9CC6F07FDC42LL /* 25 */, - 0xBF38A078243342E0LL /* 26 */, 0x5F6B343C9D2E7D04LL /* 27 */, - 0xF2C28AEB600B0EC6LL /* 28 */, 0x6C0ED85F7254BCACLL /* 29 */, - 0x71592281A4DB4FE5LL /* 30 */, 0x1967FA69CE0FED9FLL /* 31 */, - 0xFD5293F8B96545DBLL /* 32 */, 0xC879E9D7F2A7600BLL /* 33 */, - 0x860248920193194ELL /* 34 */, 0xA4F9533B2D9CC0B3LL /* 35 */, - 0x9053836C15957613LL /* 36 */, 0xDB6DCF8AFC357BF1LL /* 37 */, - 0x18BEEA7A7A370F57LL /* 38 */, 0x037117CA50B99066LL /* 39 */, - 0x6AB30A9774424A35LL /* 40 */, 0xF4E92F02E325249BLL /* 41 */, - 0x7739DB07061CCAE1LL /* 42 */, 0xD8F3B49CECA42A05LL /* 43 */, - 0xBD56BE3F51382F73LL /* 44 */, 0x45FAED5843B0BB28LL /* 45 */, - 0x1C813D5C11BF1F83LL /* 46 */, 0x8AF0E4B6D75FA169LL /* 47 */, - 0x33EE18A487AD9999LL /* 48 */, 0x3C26E8EAB1C94410LL /* 49 */, - 0xB510102BC0A822F9LL /* 50 */, 0x141EEF310CE6123BLL /* 51 */, - 0xFC65B90059DDB154LL /* 52 */, 0xE0158640C5E0E607LL /* 53 */, - 0x884E079826C3A3CFLL /* 54 */, 0x930D0D9523C535FDLL /* 55 */, - 0x35638D754E9A2B00LL /* 56 */, 0x4085FCCF40469DD5LL /* 57 */, - 0xC4B17AD28BE23A4CLL /* 58 */, 0xCAB2F0FC6A3E6A2ELL /* 59 */, - 0x2860971A6B943FCDLL /* 60 */, 0x3DDE6EE212E30446LL /* 61 */, - 0x6222F32AE01765AELL /* 62 */, 0x5D550BB5478308FELL /* 63 */, - 0xA9EFA98DA0EDA22ALL /* 64 */, 0xC351A71686C40DA7LL /* 65 */, - 0x1105586D9C867C84LL /* 66 */, 0xDCFFEE85FDA22853LL /* 67 */, - 0xCCFBD0262C5EEF76LL /* 68 */, 0xBAF294CB8990D201LL /* 69 */, - 0xE69464F52AFAD975LL /* 70 */, 0x94B013AFDF133E14LL /* 71 */, - 0x06A7D1A32823C958LL /* 72 */, 0x6F95FE5130F61119LL /* 73 */, - 0xD92AB34E462C06C0LL /* 74 */, 0xED7BDE33887C71D2LL /* 75 */, - 0x79746D6E6518393ELL /* 76 */, 0x5BA419385D713329LL /* 77 */, - 0x7C1BA6B948A97564LL /* 78 */, 0x31987C197BFDAC67LL /* 79 */, - 0xDE6C23C44B053D02LL /* 80 */, 0x581C49FED002D64DLL /* 81 */, - 0xDD474D6338261571LL /* 82 */, 0xAA4546C3E473D062LL /* 83 */, - 0x928FCE349455F860LL /* 84 */, 0x48161BBACAAB94D9LL /* 85 */, - 0x63912430770E6F68LL /* 86 */, 0x6EC8A5E602C6641CLL /* 87 */, - 0x87282515337DDD2BLL /* 88 */, 0x2CDA6B42034B701BLL /* 89 */, - 0xB03D37C181CB096DLL /* 90 */, 0xE108438266C71C6FLL /* 91 */, - 0x2B3180C7EB51B255LL /* 92 */, 0xDF92B82F96C08BBCLL /* 93 */, - 0x5C68C8C0A632F3BALL /* 94 */, 0x5504CC861C3D0556LL /* 95 */, - 0xABBFA4E55FB26B8FLL /* 96 */, 0x41848B0AB3BACEB4LL /* 97 */, - 0xB334A273AA445D32LL /* 98 */, 0xBCA696F0A85AD881LL /* 99 */, - 0x24F6EC65B528D56CLL /* 100 */, 0x0CE1512E90F4524ALL /* 101 */, - 0x4E9DD79D5506D35ALL /* 102 */, 0x258905FAC6CE9779LL /* 103 */, - 0x2019295B3E109B33LL /* 104 */, 0xF8A9478B73A054CCLL /* 105 */, - 0x2924F2F934417EB0LL /* 106 */, 0x3993357D536D1BC4LL /* 107 */, - 0x38A81AC21DB6FF8BLL /* 108 */, 0x47C4FBF17D6016BFLL /* 109 */, - 0x1E0FAADD7667E3F5LL /* 110 */, 0x7ABCFF62938BEB96LL /* 111 */, - 0xA78DAD948FC179C9LL /* 112 */, 0x8F1F98B72911E50DLL /* 113 */, - 0x61E48EAE27121A91LL /* 114 */, 0x4D62F7AD31859808LL /* 115 */, - 0xECEBA345EF5CEAEBLL /* 116 */, 0xF5CEB25EBC9684CELL /* 117 */, - 0xF633E20CB7F76221LL /* 118 */, 0xA32CDF06AB8293E4LL /* 119 */, - 0x985A202CA5EE2CA4LL /* 120 */, 0xCF0B8447CC8A8FB1LL /* 121 */, - 0x9F765244979859A3LL /* 122 */, 0xA8D516B1A1240017LL /* 123 */, - 0x0BD7BA3EBB5DC726LL /* 124 */, 0xE54BCA55B86ADB39LL /* 125 */, - 0x1D7A3AFD6C478063LL /* 126 */, 0x519EC608E7669EDDLL /* 127 */, - 0x0E5715A2D149AA23LL /* 128 */, 0x177D4571848FF194LL /* 129 */, - 0xEEB55F3241014C22LL /* 130 */, 0x0F5E5CA13A6E2EC2LL /* 131 */, - 0x8029927B75F5C361LL /* 132 */, 0xAD139FABC3D6E436LL /* 133 */, - 0x0D5DF1A94CCF402FLL /* 134 */, 0x3E8BD948BEA5DFC8LL /* 135 */, - 0xA5A0D357BD3FF77ELL /* 136 */, 0xA2D12E251F74F645LL /* 137 */, - 0x66FD9E525E81A082LL /* 138 */, 0x2E0C90CE7F687A49LL /* 139 */, - 0xC2E8BCBEBA973BC5LL /* 140 */, 0x000001BCE509745FLL /* 141 */, - 0x423777BBE6DAB3D6LL /* 142 */, 0xD1661C7EAEF06EB5LL /* 143 */, - 0xA1781F354DAACFD8LL /* 144 */, 0x2D11284A2B16AFFCLL /* 145 */, - 0xF1FC4F67FA891D1FLL /* 146 */, 0x73ECC25DCB920ADALL /* 147 */, - 0xAE610C22C2A12651LL /* 148 */, 0x96E0A810D356B78ALL /* 149 */, - 0x5A9A381F2FE7870FLL /* 150 */, 0xD5AD62EDE94E5530LL /* 151 */, - 0xD225E5E8368D1427LL /* 152 */, 0x65977B70C7AF4631LL /* 153 */, - 0x99F889B2DE39D74FLL /* 154 */, 0x233F30BF54E1D143LL /* 155 */, - 0x9A9675D3D9A63C97LL /* 156 */, 0x5470554FF334F9A8LL /* 157 */, - 0x166ACB744A4F5688LL /* 158 */, 0x70C74CAAB2E4AEADLL /* 159 */, - 0xF0D091646F294D12LL /* 160 */, 0x57B82A89684031D1LL /* 161 */, - 0xEFD95A5A61BE0B6BLL /* 162 */, 0x2FBD12E969F2F29ALL /* 163 */, - 0x9BD37013FEFF9FE8LL /* 164 */, 0x3F9B0404D6085A06LL /* 165 */, - 0x4940C1F3166CFE15LL /* 166 */, 0x09542C4DCDF3DEFBLL /* 167 */, - 0xB4C5218385CD5CE3LL /* 168 */, 0xC935B7DC4462A641LL /* 169 */, - 0x3417F8A68ED3B63FLL /* 170 */, 0xB80959295B215B40LL /* 171 */, - 0xF99CDAEF3B8C8572LL /* 172 */, 0x018C0614F8FCB95DLL /* 173 */, - 0x1B14ACCD1A3ACDF3LL /* 174 */, 0x84D471F200BB732DLL /* 175 */, - 0xC1A3110E95E8DA16LL /* 176 */, 0x430A7220BF1A82B8LL /* 177 */, - 0xB77E090D39DF210ELL /* 178 */, 0x5EF4BD9F3CD05E9DLL /* 179 */, - 0x9D4FF6DA7E57A444LL /* 180 */, 0xDA1D60E183D4A5F8LL /* 181 */, - 0xB287C38417998E47LL /* 182 */, 0xFE3EDC121BB31886LL /* 183 */, - 0xC7FE3CCC980CCBEFLL /* 184 */, 0xE46FB590189BFD03LL /* 185 */, - 0x3732FD469A4C57DCLL /* 186 */, 0x7EF700A07CF1AD65LL /* 187 */, - 0x59C64468A31D8859LL /* 188 */, 0x762FB0B4D45B61F6LL /* 189 */, - 0x155BAED099047718LL /* 190 */, 0x68755E4C3D50BAA6LL /* 191 */, - 0xE9214E7F22D8B4DFLL /* 192 */, 0x2ADDBF532EAC95F4LL /* 193 */, - 0x32AE3909B4BD0109LL /* 194 */, 0x834DF537B08E3450LL /* 195 */, - 0xFA209DA84220728DLL /* 196 */, 0x9E691D9B9EFE23F7LL /* 197 */, - 0x0446D288C4AE8D7FLL /* 198 */, 0x7B4CC524E169785BLL /* 199 */, - 0x21D87F0135CA1385LL /* 200 */, 0xCEBB400F137B8AA5LL /* 201 */, - 0x272E2B66580796BELL /* 202 */, 0x3612264125C2B0DELL /* 203 */, - 0x057702BDAD1EFBB2LL /* 204 */, 0xD4BABB8EACF84BE9LL /* 205 */, - 0x91583139641BC67BLL /* 206 */, 0x8BDC2DE08036E024LL /* 207 */, - 0x603C8156F49F68EDLL /* 208 */, 0xF7D236F7DBEF5111LL /* 209 */, - 0x9727C4598AD21E80LL /* 210 */, 0xA08A0896670A5FD7LL /* 211 */, - 0xCB4A8F4309EBA9CBLL /* 212 */, 0x81AF564B0F7036A1LL /* 213 */, - 0xC0B99AA778199ABDLL /* 214 */, 0x959F1EC83FC8E952LL /* 215 */, - 0x8C505077794A81B9LL /* 216 */, 0x3ACAAF8F056338F0LL /* 217 */, - 0x07B43F50627A6778LL /* 218 */, 0x4A44AB49F5ECCC77LL /* 219 */, - 0x3BC3D6E4B679EE98LL /* 220 */, 0x9CC0D4D1CF14108CLL /* 221 */, - 0x4406C00B206BC8A0LL /* 222 */, 0x82A18854C8D72D89LL /* 223 */, - 0x67E366B35C3C432CLL /* 224 */, 0xB923DD61102B37F2LL /* 225 */, - 0x56AB2779D884271DLL /* 226 */, 0xBE83E1B0FF1525AFLL /* 227 */, - 0xFB7C65D4217E49A9LL /* 228 */, 0x6BDBE0E76D48E7D4LL /* 229 */, - 0x08DF828745D9179ELL /* 230 */, 0x22EA6A9ADD53BD34LL /* 231 */, - 0xE36E141C5622200ALL /* 232 */, 0x7F805D1B8CB750EELL /* 233 */, - 0xAFE5C7A59F58E837LL /* 234 */, 0xE27F996A4FB1C23CLL /* 235 */, - 0xD3867DFB0775F0D0LL /* 236 */, 0xD0E673DE6E88891ALL /* 237 */, - 0x123AEB9EAFB86C25LL /* 238 */, 0x30F1D5D5C145B895LL /* 239 */, - 0xBB434A2DEE7269E7LL /* 240 */, 0x78CB67ECF931FA38LL /* 241 */, - 0xF33B0372323BBF9CLL /* 242 */, 0x52D66336FB279C74LL /* 243 */, - 0x505F33AC0AFB4EAALL /* 244 */, 0xE8A5CD99A2CCE187LL /* 245 */, - 0x534974801E2D30BBLL /* 246 */, 0x8D2D5711D5876D90LL /* 247 */, - 0x1F1A412891BC038ELL /* 248 */, 0xD6E2E71D82E56648LL /* 249 */, - 0x74036C3A497732B7LL /* 250 */, 0x89B67ED96361F5ABLL /* 251 */, - 0xFFED95D8F1EA02A2LL /* 252 */, 0xE72B3BD61464D43DLL /* 253 */, - 0xA6300F170BDC4820LL /* 254 */, 0xEBC18760ED78A77ALL /* 255 */, - 0xE6A6BE5A05A12138LL /* 256 */, 0xB5A122A5B4F87C98LL /* 257 */, - 0x563C6089140B6990LL /* 258 */, 0x4C46CB2E391F5DD5LL /* 259 */, - 0xD932ADDBC9B79434LL /* 260 */, 0x08EA70E42015AFF5LL /* 261 */, - 0xD765A6673E478CF1LL /* 262 */, 0xC4FB757EAB278D99LL /* 263 */, - 0xDF11C6862D6E0692LL /* 264 */, 0xDDEB84F10D7F3B16LL /* 265 */, - 0x6F2EF604A665EA04LL /* 266 */, 0x4A8E0F0FF0E0DFB3LL /* 267 */, - 0xA5EDEEF83DBCBA51LL /* 268 */, 0xFC4F0A2A0EA4371ELL /* 269 */, - 0xE83E1DA85CB38429LL /* 270 */, 0xDC8FF882BA1B1CE2LL /* 271 */, - 0xCD45505E8353E80DLL /* 272 */, 0x18D19A00D4DB0717LL /* 273 */, - 0x34A0CFEDA5F38101LL /* 274 */, 0x0BE77E518887CAF2LL /* 275 */, - 0x1E341438B3C45136LL /* 276 */, 0xE05797F49089CCF9LL /* 277 */, - 0xFFD23F9DF2591D14LL /* 278 */, 0x543DDA228595C5CDLL /* 279 */, - 0x661F81FD99052A33LL /* 280 */, 0x8736E641DB0F7B76LL /* 281 */, - 0x15227725418E5307LL /* 282 */, 0xE25F7F46162EB2FALL /* 283 */, - 0x48A8B2126C13D9FELL /* 284 */, 0xAFDC541792E76EEALL /* 285 */, - 0x03D912BFC6D1898FLL /* 286 */, 0x31B1AAFA1B83F51BLL /* 287 */, - 0xF1AC2796E42AB7D9LL /* 288 */, 0x40A3A7D7FCD2EBACLL /* 289 */, - 0x1056136D0AFBBCC5LL /* 290 */, 0x7889E1DD9A6D0C85LL /* 291 */, - 0xD33525782A7974AALL /* 292 */, 0xA7E25D09078AC09BLL /* 293 */, - 0xBD4138B3EAC6EDD0LL /* 294 */, 0x920ABFBE71EB9E70LL /* 295 */, - 0xA2A5D0F54FC2625CLL /* 296 */, 0xC054E36B0B1290A3LL /* 297 */, - 0xF6DD59FF62FE932BLL /* 298 */, 0x3537354511A8AC7DLL /* 299 */, - 0xCA845E9172FADCD4LL /* 300 */, 0x84F82B60329D20DCLL /* 301 */, - 0x79C62CE1CD672F18LL /* 302 */, 0x8B09A2ADD124642CLL /* 303 */, - 0xD0C1E96A19D9E726LL /* 304 */, 0x5A786A9B4BA9500CLL /* 305 */, - 0x0E020336634C43F3LL /* 306 */, 0xC17B474AEB66D822LL /* 307 */, - 0x6A731AE3EC9BAAC2LL /* 308 */, 0x8226667AE0840258LL /* 309 */, - 0x67D4567691CAECA5LL /* 310 */, 0x1D94155C4875ADB5LL /* 311 */, - 0x6D00FD985B813FDFLL /* 312 */, 0x51286EFCB774CD06LL /* 313 */, - 0x5E8834471FA744AFLL /* 314 */, 0xF72CA0AEE761AE2ELL /* 315 */, - 0xBE40E4CDAEE8E09ALL /* 316 */, 0xE9970BBB5118F665LL /* 317 */, - 0x726E4BEB33DF1964LL /* 318 */, 0x703B000729199762LL /* 319 */, - 0x4631D816F5EF30A7LL /* 320 */, 0xB880B5B51504A6BELL /* 321 */, - 0x641793C37ED84B6CLL /* 322 */, 0x7B21ED77F6E97D96LL /* 323 */, - 0x776306312EF96B73LL /* 324 */, 0xAE528948E86FF3F4LL /* 325 */, - 0x53DBD7F286A3F8F8LL /* 326 */, 0x16CADCE74CFC1063LL /* 327 */, - 0x005C19BDFA52C6DDLL /* 328 */, 0x68868F5D64D46AD3LL /* 329 */, - 0x3A9D512CCF1E186ALL /* 330 */, 0x367E62C2385660AELL /* 331 */, - 0xE359E7EA77DCB1D7LL /* 332 */, 0x526C0773749ABE6ELL /* 333 */, - 0x735AE5F9D09F734BLL /* 334 */, 0x493FC7CC8A558BA8LL /* 335 */, - 0xB0B9C1533041AB45LL /* 336 */, 0x321958BA470A59BDLL /* 337 */, - 0x852DB00B5F46C393LL /* 338 */, 0x91209B2BD336B0E5LL /* 339 */, - 0x6E604F7D659EF19FLL /* 340 */, 0xB99A8AE2782CCB24LL /* 341 */, - 0xCCF52AB6C814C4C7LL /* 342 */, 0x4727D9AFBE11727BLL /* 343 */, - 0x7E950D0C0121B34DLL /* 344 */, 0x756F435670AD471FLL /* 345 */, - 0xF5ADD442615A6849LL /* 346 */, 0x4E87E09980B9957ALL /* 347 */, - 0x2ACFA1DF50AEE355LL /* 348 */, 0xD898263AFD2FD556LL /* 349 */, - 0xC8F4924DD80C8FD6LL /* 350 */, 0xCF99CA3D754A173ALL /* 351 */, - 0xFE477BACAF91BF3CLL /* 352 */, 0xED5371F6D690C12DLL /* 353 */, - 0x831A5C285E687094LL /* 354 */, 0xC5D3C90A3708A0A4LL /* 355 */, - 0x0F7F903717D06580LL /* 356 */, 0x19F9BB13B8FDF27FLL /* 357 */, - 0xB1BD6F1B4D502843LL /* 358 */, 0x1C761BA38FFF4012LL /* 359 */, - 0x0D1530C4E2E21F3BLL /* 360 */, 0x8943CE69A7372C8ALL /* 361 */, - 0xE5184E11FEB5CE66LL /* 362 */, 0x618BDB80BD736621LL /* 363 */, - 0x7D29BAD68B574D0BLL /* 364 */, 0x81BB613E25E6FE5BLL /* 365 */, - 0x071C9C10BC07913FLL /* 366 */, 0xC7BEEB7909AC2D97LL /* 367 */, - 0xC3E58D353BC5D757LL /* 368 */, 0xEB017892F38F61E8LL /* 369 */, - 0xD4EFFB9C9B1CC21ALL /* 370 */, 0x99727D26F494F7ABLL /* 371 */, - 0xA3E063A2956B3E03LL /* 372 */, 0x9D4A8B9A4AA09C30LL /* 373 */, - 0x3F6AB7D500090FB4LL /* 374 */, 0x9CC0F2A057268AC0LL /* 375 */, - 0x3DEE9D2DEDBF42D1LL /* 376 */, 0x330F49C87960A972LL /* 377 */, - 0xC6B2720287421B41LL /* 378 */, 0x0AC59EC07C00369CLL /* 379 */, - 0xEF4EAC49CB353425LL /* 380 */, 0xF450244EEF0129D8LL /* 381 */, - 0x8ACC46E5CAF4DEB6LL /* 382 */, 0x2FFEAB63989263F7LL /* 383 */, - 0x8F7CB9FE5D7A4578LL /* 384 */, 0x5BD8F7644E634635LL /* 385 */, - 0x427A7315BF2DC900LL /* 386 */, 0x17D0C4AA2125261CLL /* 387 */, - 0x3992486C93518E50LL /* 388 */, 0xB4CBFEE0A2D7D4C3LL /* 389 */, - 0x7C75D6202C5DDD8DLL /* 390 */, 0xDBC295D8E35B6C61LL /* 391 */, - 0x60B369D302032B19LL /* 392 */, 0xCE42685FDCE44132LL /* 393 */, - 0x06F3DDB9DDF65610LL /* 394 */, 0x8EA4D21DB5E148F0LL /* 395 */, - 0x20B0FCE62FCD496FLL /* 396 */, 0x2C1B912358B0EE31LL /* 397 */, - 0xB28317B818F5A308LL /* 398 */, 0xA89C1E189CA6D2CFLL /* 399 */, - 0x0C6B18576AAADBC8LL /* 400 */, 0xB65DEAA91299FAE3LL /* 401 */, - 0xFB2B794B7F1027E7LL /* 402 */, 0x04E4317F443B5BEBLL /* 403 */, - 0x4B852D325939D0A6LL /* 404 */, 0xD5AE6BEEFB207FFCLL /* 405 */, - 0x309682B281C7D374LL /* 406 */, 0xBAE309A194C3B475LL /* 407 */, - 0x8CC3F97B13B49F05LL /* 408 */, 0x98A9422FF8293967LL /* 409 */, - 0x244B16B01076FF7CLL /* 410 */, 0xF8BF571C663D67EELL /* 411 */, - 0x1F0D6758EEE30DA1LL /* 412 */, 0xC9B611D97ADEB9B7LL /* 413 */, - 0xB7AFD5887B6C57A2LL /* 414 */, 0x6290AE846B984FE1LL /* 415 */, - 0x94DF4CDEACC1A5FDLL /* 416 */, 0x058A5BD1C5483AFFLL /* 417 */, - 0x63166CC142BA3C37LL /* 418 */, 0x8DB8526EB2F76F40LL /* 419 */, - 0xE10880036F0D6D4ELL /* 420 */, 0x9E0523C9971D311DLL /* 421 */, - 0x45EC2824CC7CD691LL /* 422 */, 0x575B8359E62382C9LL /* 423 */, - 0xFA9E400DC4889995LL /* 424 */, 0xD1823ECB45721568LL /* 425 */, - 0xDAFD983B8206082FLL /* 426 */, 0xAA7D29082386A8CBLL /* 427 */, - 0x269FCD4403B87588LL /* 428 */, 0x1B91F5F728BDD1E0LL /* 429 */, - 0xE4669F39040201F6LL /* 430 */, 0x7A1D7C218CF04ADELL /* 431 */, - 0x65623C29D79CE5CELL /* 432 */, 0x2368449096C00BB1LL /* 433 */, - 0xAB9BF1879DA503BALL /* 434 */, 0xBC23ECB1A458058ELL /* 435 */, - 0x9A58DF01BB401ECCLL /* 436 */, 0xA070E868A85F143DLL /* 437 */, - 0x4FF188307DF2239ELL /* 438 */, 0x14D565B41A641183LL /* 439 */, - 0xEE13337452701602LL /* 440 */, 0x950E3DCF3F285E09LL /* 441 */, - 0x59930254B9C80953LL /* 442 */, 0x3BF299408930DA6DLL /* 443 */, - 0xA955943F53691387LL /* 444 */, 0xA15EDECAA9CB8784LL /* 445 */, - 0x29142127352BE9A0LL /* 446 */, 0x76F0371FFF4E7AFBLL /* 447 */, - 0x0239F450274F2228LL /* 448 */, 0xBB073AF01D5E868BLL /* 449 */, - 0xBFC80571C10E96C1LL /* 450 */, 0xD267088568222E23LL /* 451 */, - 0x9671A3D48E80B5B0LL /* 452 */, 0x55B5D38AE193BB81LL /* 453 */, - 0x693AE2D0A18B04B8LL /* 454 */, 0x5C48B4ECADD5335FLL /* 455 */, - 0xFD743B194916A1CALL /* 456 */, 0x2577018134BE98C4LL /* 457 */, - 0xE77987E83C54A4ADLL /* 458 */, 0x28E11014DA33E1B9LL /* 459 */, - 0x270CC59E226AA213LL /* 460 */, 0x71495F756D1A5F60LL /* 461 */, - 0x9BE853FB60AFEF77LL /* 462 */, 0xADC786A7F7443DBFLL /* 463 */, - 0x0904456173B29A82LL /* 464 */, 0x58BC7A66C232BD5ELL /* 465 */, - 0xF306558C673AC8B2LL /* 466 */, 0x41F639C6B6C9772ALL /* 467 */, - 0x216DEFE99FDA35DALL /* 468 */, 0x11640CC71C7BE615LL /* 469 */, - 0x93C43694565C5527LL /* 470 */, 0xEA038E6246777839LL /* 471 */, - 0xF9ABF3CE5A3E2469LL /* 472 */, 0x741E768D0FD312D2LL /* 473 */, - 0x0144B883CED652C6LL /* 474 */, 0xC20B5A5BA33F8552LL /* 475 */, - 0x1AE69633C3435A9DLL /* 476 */, 0x97A28CA4088CFDECLL /* 477 */, - 0x8824A43C1E96F420LL /* 478 */, 0x37612FA66EEEA746LL /* 479 */, - 0x6B4CB165F9CF0E5ALL /* 480 */, 0x43AA1C06A0ABFB4ALL /* 481 */, - 0x7F4DC26FF162796BLL /* 482 */, 0x6CBACC8E54ED9B0FLL /* 483 */, - 0xA6B7FFEFD2BB253ELL /* 484 */, 0x2E25BC95B0A29D4FLL /* 485 */, - 0x86D6A58BDEF1388CLL /* 486 */, 0xDED74AC576B6F054LL /* 487 */, - 0x8030BDBC2B45805DLL /* 488 */, 0x3C81AF70E94D9289LL /* 489 */, - 0x3EFF6DDA9E3100DBLL /* 490 */, 0xB38DC39FDFCC8847LL /* 491 */, - 0x123885528D17B87ELL /* 492 */, 0xF2DA0ED240B1B642LL /* 493 */, - 0x44CEFADCD54BF9A9LL /* 494 */, 0x1312200E433C7EE6LL /* 495 */, - 0x9FFCC84F3A78C748LL /* 496 */, 0xF0CD1F72248576BBLL /* 497 */, - 0xEC6974053638CFE4LL /* 498 */, 0x2BA7B67C0CEC4E4CLL /* 499 */, - 0xAC2F4DF3E5CE32EDLL /* 500 */, 0xCB33D14326EA4C11LL /* 501 */, - 0xA4E9044CC77E58BCLL /* 502 */, 0x5F513293D934FCEFLL /* 503 */, - 0x5DC9645506E55444LL /* 504 */, 0x50DE418F317DE40ALL /* 505 */, - 0x388CB31A69DDE259LL /* 506 */, 0x2DB4A83455820A86LL /* 507 */, - 0x9010A91E84711AE9LL /* 508 */, 0x4DF7F0B7B1498371LL /* 509 */, - 0xD62A2EABC0977179LL /* 510 */, 0x22FAC097AA8D5C0ELL /* 511 */, - 0xF49FCC2FF1DAF39BLL /* 512 */, 0x487FD5C66FF29281LL /* 513 */, - 0xE8A30667FCDCA83FLL /* 514 */, 0x2C9B4BE3D2FCCE63LL /* 515 */, - 0xDA3FF74B93FBBBC2LL /* 516 */, 0x2FA165D2FE70BA66LL /* 517 */, - 0xA103E279970E93D4LL /* 518 */, 0xBECDEC77B0E45E71LL /* 519 */, - 0xCFB41E723985E497LL /* 520 */, 0xB70AAA025EF75017LL /* 521 */, - 0xD42309F03840B8E0LL /* 522 */, 0x8EFC1AD035898579LL /* 523 */, - 0x96C6920BE2B2ABC5LL /* 524 */, 0x66AF4163375A9172LL /* 525 */, - 0x2174ABDCCA7127FBLL /* 526 */, 0xB33CCEA64A72FF41LL /* 527 */, - 0xF04A4933083066A5LL /* 528 */, 0x8D970ACDD7289AF5LL /* 529 */, - 0x8F96E8E031C8C25ELL /* 530 */, 0xF3FEC02276875D47LL /* 531 */, - 0xEC7BF310056190DDLL /* 532 */, 0xF5ADB0AEBB0F1491LL /* 533 */, - 0x9B50F8850FD58892LL /* 534 */, 0x4975488358B74DE8LL /* 535 */, - 0xA3354FF691531C61LL /* 536 */, 0x0702BBE481D2C6EELL /* 537 */, - 0x89FB24057DEDED98LL /* 538 */, 0xAC3075138596E902LL /* 539 */, - 0x1D2D3580172772EDLL /* 540 */, 0xEB738FC28E6BC30DLL /* 541 */, - 0x5854EF8F63044326LL /* 542 */, 0x9E5C52325ADD3BBELL /* 543 */, - 0x90AA53CF325C4623LL /* 544 */, 0xC1D24D51349DD067LL /* 545 */, - 0x2051CFEEA69EA624LL /* 546 */, 0x13220F0A862E7E4FLL /* 547 */, - 0xCE39399404E04864LL /* 548 */, 0xD9C42CA47086FCB7LL /* 549 */, - 0x685AD2238A03E7CCLL /* 550 */, 0x066484B2AB2FF1DBLL /* 551 */, - 0xFE9D5D70EFBF79ECLL /* 552 */, 0x5B13B9DD9C481854LL /* 553 */, - 0x15F0D475ED1509ADLL /* 554 */, 0x0BEBCD060EC79851LL /* 555 */, - 0xD58C6791183AB7F8LL /* 556 */, 0xD1187C5052F3EEE4LL /* 557 */, - 0xC95D1192E54E82FFLL /* 558 */, 0x86EEA14CB9AC6CA2LL /* 559 */, - 0x3485BEB153677D5DLL /* 560 */, 0xDD191D781F8C492ALL /* 561 */, - 0xF60866BAA784EBF9LL /* 562 */, 0x518F643BA2D08C74LL /* 563 */, - 0x8852E956E1087C22LL /* 564 */, 0xA768CB8DC410AE8DLL /* 565 */, - 0x38047726BFEC8E1ALL /* 566 */, 0xA67738B4CD3B45AALL /* 567 */, - 0xAD16691CEC0DDE19LL /* 568 */, 0xC6D4319380462E07LL /* 569 */, - 0xC5A5876D0BA61938LL /* 570 */, 0x16B9FA1FA58FD840LL /* 571 */, - 0x188AB1173CA74F18LL /* 572 */, 0xABDA2F98C99C021FLL /* 573 */, - 0x3E0580AB134AE816LL /* 574 */, 0x5F3B05B773645ABBLL /* 575 */, - 0x2501A2BE5575F2F6LL /* 576 */, 0x1B2F74004E7E8BA9LL /* 577 */, - 0x1CD7580371E8D953LL /* 578 */, 0x7F6ED89562764E30LL /* 579 */, - 0xB15926FF596F003DLL /* 580 */, 0x9F65293DA8C5D6B9LL /* 581 */, - 0x6ECEF04DD690F84CLL /* 582 */, 0x4782275FFF33AF88LL /* 583 */, - 0xE41433083F820801LL /* 584 */, 0xFD0DFE409A1AF9B5LL /* 585 */, - 0x4325A3342CDB396BLL /* 586 */, 0x8AE77E62B301B252LL /* 587 */, - 0xC36F9E9F6655615ALL /* 588 */, 0x85455A2D92D32C09LL /* 589 */, - 0xF2C7DEA949477485LL /* 590 */, 0x63CFB4C133A39EBALL /* 591 */, - 0x83B040CC6EBC5462LL /* 592 */, 0x3B9454C8FDB326B0LL /* 593 */, - 0x56F56A9E87FFD78CLL /* 594 */, 0x2DC2940D99F42BC6LL /* 595 */, - 0x98F7DF096B096E2DLL /* 596 */, 0x19A6E01E3AD852BFLL /* 597 */, - 0x42A99CCBDBD4B40BLL /* 598 */, 0xA59998AF45E9C559LL /* 599 */, - 0x366295E807D93186LL /* 600 */, 0x6B48181BFAA1F773LL /* 601 */, - 0x1FEC57E2157A0A1DLL /* 602 */, 0x4667446AF6201AD5LL /* 603 */, - 0xE615EBCACFB0F075LL /* 604 */, 0xB8F31F4F68290778LL /* 605 */, - 0x22713ED6CE22D11ELL /* 606 */, 0x3057C1A72EC3C93BLL /* 607 */, - 0xCB46ACC37C3F1F2FLL /* 608 */, 0xDBB893FD02AAF50ELL /* 609 */, - 0x331FD92E600B9FCFLL /* 610 */, 0xA498F96148EA3AD6LL /* 611 */, - 0xA8D8426E8B6A83EALL /* 612 */, 0xA089B274B7735CDCLL /* 613 */, - 0x87F6B3731E524A11LL /* 614 */, 0x118808E5CBC96749LL /* 615 */, - 0x9906E4C7B19BD394LL /* 616 */, 0xAFED7F7E9B24A20CLL /* 617 */, - 0x6509EADEEB3644A7LL /* 618 */, 0x6C1EF1D3E8EF0EDELL /* 619 */, - 0xB9C97D43E9798FB4LL /* 620 */, 0xA2F2D784740C28A3LL /* 621 */, - 0x7B8496476197566FLL /* 622 */, 0x7A5BE3E6B65F069DLL /* 623 */, - 0xF96330ED78BE6F10LL /* 624 */, 0xEEE60DE77A076A15LL /* 625 */, - 0x2B4BEE4AA08B9BD0LL /* 626 */, 0x6A56A63EC7B8894ELL /* 627 */, - 0x02121359BA34FEF4LL /* 628 */, 0x4CBF99F8283703FCLL /* 629 */, - 0x398071350CAF30C8LL /* 630 */, 0xD0A77A89F017687ALL /* 631 */, - 0xF1C1A9EB9E423569LL /* 632 */, 0x8C7976282DEE8199LL /* 633 */, - 0x5D1737A5DD1F7ABDLL /* 634 */, 0x4F53433C09A9FA80LL /* 635 */, - 0xFA8B0C53DF7CA1D9LL /* 636 */, 0x3FD9DCBC886CCB77LL /* 637 */, - 0xC040917CA91B4720LL /* 638 */, 0x7DD00142F9D1DCDFLL /* 639 */, - 0x8476FC1D4F387B58LL /* 640 */, 0x23F8E7C5F3316503LL /* 641 */, - 0x032A2244E7E37339LL /* 642 */, 0x5C87A5D750F5A74BLL /* 643 */, - 0x082B4CC43698992ELL /* 644 */, 0xDF917BECB858F63CLL /* 645 */, - 0x3270B8FC5BF86DDALL /* 646 */, 0x10AE72BB29B5DD76LL /* 647 */, - 0x576AC94E7700362BLL /* 648 */, 0x1AD112DAC61EFB8FLL /* 649 */, - 0x691BC30EC5FAA427LL /* 650 */, 0xFF246311CC327143LL /* 651 */, - 0x3142368E30E53206LL /* 652 */, 0x71380E31E02CA396LL /* 653 */, - 0x958D5C960AAD76F1LL /* 654 */, 0xF8D6F430C16DA536LL /* 655 */, - 0xC8FFD13F1BE7E1D2LL /* 656 */, 0x7578AE66004DDBE1LL /* 657 */, - 0x05833F01067BE646LL /* 658 */, 0xBB34B5AD3BFE586DLL /* 659 */, - 0x095F34C9A12B97F0LL /* 660 */, 0x247AB64525D60CA8LL /* 661 */, - 0xDCDBC6F3017477D1LL /* 662 */, 0x4A2E14D4DECAD24DLL /* 663 */, - 0xBDB5E6D9BE0A1EEBLL /* 664 */, 0x2A7E70F7794301ABLL /* 665 */, - 0xDEF42D8A270540FDLL /* 666 */, 0x01078EC0A34C22C1LL /* 667 */, - 0xE5DE511AF4C16387LL /* 668 */, 0x7EBB3A52BD9A330ALL /* 669 */, - 0x77697857AA7D6435LL /* 670 */, 0x004E831603AE4C32LL /* 671 */, - 0xE7A21020AD78E312LL /* 672 */, 0x9D41A70C6AB420F2LL /* 673 */, - 0x28E06C18EA1141E6LL /* 674 */, 0xD2B28CBD984F6B28LL /* 675 */, - 0x26B75F6C446E9D83LL /* 676 */, 0xBA47568C4D418D7FLL /* 677 */, - 0xD80BADBFE6183D8ELL /* 678 */, 0x0E206D7F5F166044LL /* 679 */, - 0xE258A43911CBCA3ELL /* 680 */, 0x723A1746B21DC0BCLL /* 681 */, - 0xC7CAA854F5D7CDD3LL /* 682 */, 0x7CAC32883D261D9CLL /* 683 */, - 0x7690C26423BA942CLL /* 684 */, 0x17E55524478042B8LL /* 685 */, - 0xE0BE477656A2389FLL /* 686 */, 0x4D289B5E67AB2DA0LL /* 687 */, - 0x44862B9C8FBBFD31LL /* 688 */, 0xB47CC8049D141365LL /* 689 */, - 0x822C1B362B91C793LL /* 690 */, 0x4EB14655FB13DFD8LL /* 691 */, - 0x1ECBBA0714E2A97BLL /* 692 */, 0x6143459D5CDE5F14LL /* 693 */, - 0x53A8FBF1D5F0AC89LL /* 694 */, 0x97EA04D81C5E5B00LL /* 695 */, - 0x622181A8D4FDB3F3LL /* 696 */, 0xE9BCD341572A1208LL /* 697 */, - 0x1411258643CCE58ALL /* 698 */, 0x9144C5FEA4C6E0A4LL /* 699 */, - 0x0D33D06565CF620FLL /* 700 */, 0x54A48D489F219CA1LL /* 701 */, - 0xC43E5EAC6D63C821LL /* 702 */, 0xA9728B3A72770DAFLL /* 703 */, - 0xD7934E7B20DF87EFLL /* 704 */, 0xE35503B61A3E86E5LL /* 705 */, - 0xCAE321FBC819D504LL /* 706 */, 0x129A50B3AC60BFA6LL /* 707 */, - 0xCD5E68EA7E9FB6C3LL /* 708 */, 0xB01C90199483B1C7LL /* 709 */, - 0x3DE93CD5C295376CLL /* 710 */, 0xAED52EDF2AB9AD13LL /* 711 */, - 0x2E60F512C0A07884LL /* 712 */, 0xBC3D86A3E36210C9LL /* 713 */, - 0x35269D9B163951CELL /* 714 */, 0x0C7D6E2AD0CDB5FALL /* 715 */, - 0x59E86297D87F5733LL /* 716 */, 0x298EF221898DB0E7LL /* 717 */, - 0x55000029D1A5AA7ELL /* 718 */, 0x8BC08AE1B5061B45LL /* 719 */, - 0xC2C31C2B6C92703ALL /* 720 */, 0x94CC596BAF25EF42LL /* 721 */, - 0x0A1D73DB22540456LL /* 722 */, 0x04B6A0F9D9C4179ALL /* 723 */, - 0xEFFDAFA2AE3D3C60LL /* 724 */, 0xF7C8075BB49496C4LL /* 725 */, - 0x9CC5C7141D1CD4E3LL /* 726 */, 0x78BD1638218E5534LL /* 727 */, - 0xB2F11568F850246ALL /* 728 */, 0xEDFABCFA9502BC29LL /* 729 */, - 0x796CE5F2DA23051BLL /* 730 */, 0xAAE128B0DC93537CLL /* 731 */, - 0x3A493DA0EE4B29AELL /* 732 */, 0xB5DF6B2C416895D7LL /* 733 */, - 0xFCABBD25122D7F37LL /* 734 */, 0x70810B58105DC4B1LL /* 735 */, - 0xE10FDD37F7882A90LL /* 736 */, 0x524DCAB5518A3F5CLL /* 737 */, - 0x3C9E85878451255BLL /* 738 */, 0x4029828119BD34E2LL /* 739 */, - 0x74A05B6F5D3CECCBLL /* 740 */, 0xB610021542E13ECALL /* 741 */, - 0x0FF979D12F59E2ACLL /* 742 */, 0x6037DA27E4F9CC50LL /* 743 */, - 0x5E92975A0DF1847DLL /* 744 */, 0xD66DE190D3E623FELL /* 745 */, - 0x5032D6B87B568048LL /* 746 */, 0x9A36B7CE8235216ELL /* 747 */, - 0x80272A7A24F64B4ALL /* 748 */, 0x93EFED8B8C6916F7LL /* 749 */, - 0x37DDBFF44CCE1555LL /* 750 */, 0x4B95DB5D4B99BD25LL /* 751 */, - 0x92D3FDA169812FC0LL /* 752 */, 0xFB1A4A9A90660BB6LL /* 753 */, - 0x730C196946A4B9B2LL /* 754 */, 0x81E289AA7F49DA68LL /* 755 */, - 0x64669A0F83B1A05FLL /* 756 */, 0x27B3FF7D9644F48BLL /* 757 */, - 0xCC6B615C8DB675B3LL /* 758 */, 0x674F20B9BCEBBE95LL /* 759 */, - 0x6F31238275655982LL /* 760 */, 0x5AE488713E45CF05LL /* 761 */, - 0xBF619F9954C21157LL /* 762 */, 0xEABAC46040A8EAE9LL /* 763 */, - 0x454C6FE9F2C0C1CDLL /* 764 */, 0x419CF6496412691CLL /* 765 */, - 0xD3DC3BEF265B0F70LL /* 766 */, 0x6D0E60F5C3578A9ELL /* 767 */, - 0x5B0E608526323C55LL /* 768 */, 0x1A46C1A9FA1B59F5LL /* 769 */, - 0xA9E245A17C4C8FFALL /* 770 */, 0x65CA5159DB2955D7LL /* 771 */, - 0x05DB0A76CE35AFC2LL /* 772 */, 0x81EAC77EA9113D45LL /* 773 */, - 0x528EF88AB6AC0A0DLL /* 774 */, 0xA09EA253597BE3FFLL /* 775 */, - 0x430DDFB3AC48CD56LL /* 776 */, 0xC4B3A67AF45CE46FLL /* 777 */, - 0x4ECECFD8FBE2D05ELL /* 778 */, 0x3EF56F10B39935F0LL /* 779 */, - 0x0B22D6829CD619C6LL /* 780 */, 0x17FD460A74DF2069LL /* 781 */, - 0x6CF8CC8E8510ED40LL /* 782 */, 0xD6C824BF3A6ECAA7LL /* 783 */, - 0x61243D581A817049LL /* 784 */, 0x048BACB6BBC163A2LL /* 785 */, - 0xD9A38AC27D44CC32LL /* 786 */, 0x7FDDFF5BAAF410ABLL /* 787 */, - 0xAD6D495AA804824BLL /* 788 */, 0xE1A6A74F2D8C9F94LL /* 789 */, - 0xD4F7851235DEE8E3LL /* 790 */, 0xFD4B7F886540D893LL /* 791 */, - 0x247C20042AA4BFDALL /* 792 */, 0x096EA1C517D1327CLL /* 793 */, - 0xD56966B4361A6685LL /* 794 */, 0x277DA5C31221057DLL /* 795 */, - 0x94D59893A43ACFF7LL /* 796 */, 0x64F0C51CCDC02281LL /* 797 */, - 0x3D33BCC4FF6189DBLL /* 798 */, 0xE005CB184CE66AF1LL /* 799 */, - 0xFF5CCD1D1DB99BEALL /* 800 */, 0xB0B854A7FE42980FLL /* 801 */, - 0x7BD46A6A718D4B9FLL /* 802 */, 0xD10FA8CC22A5FD8CLL /* 803 */, - 0xD31484952BE4BD31LL /* 804 */, 0xC7FA975FCB243847LL /* 805 */, - 0x4886ED1E5846C407LL /* 806 */, 0x28CDDB791EB70B04LL /* 807 */, - 0xC2B00BE2F573417FLL /* 808 */, 0x5C9590452180F877LL /* 809 */, - 0x7A6BDDFFF370EB00LL /* 810 */, 0xCE509E38D6D9D6A4LL /* 811 */, - 0xEBEB0F00647FA702LL /* 812 */, 0x1DCC06CF76606F06LL /* 813 */, - 0xE4D9F28BA286FF0ALL /* 814 */, 0xD85A305DC918C262LL /* 815 */, - 0x475B1D8732225F54LL /* 816 */, 0x2D4FB51668CCB5FELL /* 817 */, - 0xA679B9D9D72BBA20LL /* 818 */, 0x53841C0D912D43A5LL /* 819 */, - 0x3B7EAA48BF12A4E8LL /* 820 */, 0x781E0E47F22F1DDFLL /* 821 */, - 0xEFF20CE60AB50973LL /* 822 */, 0x20D261D19DFFB742LL /* 823 */, - 0x16A12B03062A2E39LL /* 824 */, 0x1960EB2239650495LL /* 825 */, - 0x251C16FED50EB8B8LL /* 826 */, 0x9AC0C330F826016ELL /* 827 */, - 0xED152665953E7671LL /* 828 */, 0x02D63194A6369570LL /* 829 */, - 0x5074F08394B1C987LL /* 830 */, 0x70BA598C90B25CE1LL /* 831 */, - 0x794A15810B9742F6LL /* 832 */, 0x0D5925E9FCAF8C6CLL /* 833 */, - 0x3067716CD868744ELL /* 834 */, 0x910AB077E8D7731BLL /* 835 */, - 0x6A61BBDB5AC42F61LL /* 836 */, 0x93513EFBF0851567LL /* 837 */, - 0xF494724B9E83E9D5LL /* 838 */, 0xE887E1985C09648DLL /* 839 */, - 0x34B1D3C675370CFDLL /* 840 */, 0xDC35E433BC0D255DLL /* 841 */, - 0xD0AAB84234131BE0LL /* 842 */, 0x08042A50B48B7EAFLL /* 843 */, - 0x9997C4EE44A3AB35LL /* 844 */, 0x829A7B49201799D0LL /* 845 */, - 0x263B8307B7C54441LL /* 846 */, 0x752F95F4FD6A6CA6LL /* 847 */, - 0x927217402C08C6E5LL /* 848 */, 0x2A8AB754A795D9EELL /* 849 */, - 0xA442F7552F72943DLL /* 850 */, 0x2C31334E19781208LL /* 851 */, - 0x4FA98D7CEAEE6291LL /* 852 */, 0x55C3862F665DB309LL /* 853 */, - 0xBD0610175D53B1F3LL /* 854 */, 0x46FE6CB840413F27LL /* 855 */, - 0x3FE03792DF0CFA59LL /* 856 */, 0xCFE700372EB85E8FLL /* 857 */, - 0xA7BE29E7ADBCE118LL /* 858 */, 0xE544EE5CDE8431DDLL /* 859 */, - 0x8A781B1B41F1873ELL /* 860 */, 0xA5C94C78A0D2F0E7LL /* 861 */, - 0x39412E2877B60728LL /* 862 */, 0xA1265EF3AFC9A62CLL /* 863 */, - 0xBCC2770C6A2506C5LL /* 864 */, 0x3AB66DD5DCE1CE12LL /* 865 */, - 0xE65499D04A675B37LL /* 866 */, 0x7D8F523481BFD216LL /* 867 */, - 0x0F6F64FCEC15F389LL /* 868 */, 0x74EFBE618B5B13C8LL /* 869 */, - 0xACDC82B714273E1DLL /* 870 */, 0xDD40BFE003199D17LL /* 871 */, - 0x37E99257E7E061F8LL /* 872 */, 0xFA52626904775AAALL /* 873 */, - 0x8BBBF63A463D56F9LL /* 874 */, 0xF0013F1543A26E64LL /* 875 */, - 0xA8307E9F879EC898LL /* 876 */, 0xCC4C27A4150177CCLL /* 877 */, - 0x1B432F2CCA1D3348LL /* 878 */, 0xDE1D1F8F9F6FA013LL /* 879 */, - 0x606602A047A7DDD6LL /* 880 */, 0xD237AB64CC1CB2C7LL /* 881 */, - 0x9B938E7225FCD1D3LL /* 882 */, 0xEC4E03708E0FF476LL /* 883 */, - 0xFEB2FBDA3D03C12DLL /* 884 */, 0xAE0BCED2EE43889ALL /* 885 */, - 0x22CB8923EBFB4F43LL /* 886 */, 0x69360D013CF7396DLL /* 887 */, - 0x855E3602D2D4E022LL /* 888 */, 0x073805BAD01F784CLL /* 889 */, - 0x33E17A133852F546LL /* 890 */, 0xDF4874058AC7B638LL /* 891 */, - 0xBA92B29C678AA14ALL /* 892 */, 0x0CE89FC76CFAADCDLL /* 893 */, - 0x5F9D4E0908339E34LL /* 894 */, 0xF1AFE9291F5923B9LL /* 895 */, - 0x6E3480F60F4A265FLL /* 896 */, 0xEEBF3A2AB29B841CLL /* 897 */, - 0xE21938A88F91B4ADLL /* 898 */, 0x57DFEFF845C6D3C3LL /* 899 */, - 0x2F006B0BF62CAAF2LL /* 900 */, 0x62F479EF6F75EE78LL /* 901 */, - 0x11A55AD41C8916A9LL /* 902 */, 0xF229D29084FED453LL /* 903 */, - 0x42F1C27B16B000E6LL /* 904 */, 0x2B1F76749823C074LL /* 905 */, - 0x4B76ECA3C2745360LL /* 906 */, 0x8C98F463B91691BDLL /* 907 */, - 0x14BCC93CF1ADE66ALL /* 908 */, 0x8885213E6D458397LL /* 909 */, - 0x8E177DF0274D4711LL /* 910 */, 0xB49B73B5503F2951LL /* 911 */, - 0x10168168C3F96B6BLL /* 912 */, 0x0E3D963B63CAB0AELL /* 913 */, - 0x8DFC4B5655A1DB14LL /* 914 */, 0xF789F1356E14DE5CLL /* 915 */, - 0x683E68AF4E51DAC1LL /* 916 */, 0xC9A84F9D8D4B0FD9LL /* 917 */, - 0x3691E03F52A0F9D1LL /* 918 */, 0x5ED86E46E1878E80LL /* 919 */, - 0x3C711A0E99D07150LL /* 920 */, 0x5A0865B20C4E9310LL /* 921 */, - 0x56FBFC1FE4F0682ELL /* 922 */, 0xEA8D5DE3105EDF9BLL /* 923 */, - 0x71ABFDB12379187ALL /* 924 */, 0x2EB99DE1BEE77B9CLL /* 925 */, - 0x21ECC0EA33CF4523LL /* 926 */, 0x59A4D7521805C7A1LL /* 927 */, - 0x3896F5EB56AE7C72LL /* 928 */, 0xAA638F3DB18F75DCLL /* 929 */, - 0x9F39358DABE9808ELL /* 930 */, 0xB7DEFA91C00B72ACLL /* 931 */, - 0x6B5541FD62492D92LL /* 932 */, 0x6DC6DEE8F92E4D5BLL /* 933 */, - 0x353F57ABC4BEEA7ELL /* 934 */, 0x735769D6DA5690CELL /* 935 */, - 0x0A234AA642391484LL /* 936 */, 0xF6F9508028F80D9DLL /* 937 */, - 0xB8E319A27AB3F215LL /* 938 */, 0x31AD9C1151341A4DLL /* 939 */, - 0x773C22A57BEF5805LL /* 940 */, 0x45C7561A07968633LL /* 941 */, - 0xF913DA9E249DBE36LL /* 942 */, 0xDA652D9B78A64C68LL /* 943 */, - 0x4C27A97F3BC334EFLL /* 944 */, 0x76621220E66B17F4LL /* 945 */, - 0x967743899ACD7D0BLL /* 946 */, 0xF3EE5BCAE0ED6782LL /* 947 */, - 0x409F753600C879FCLL /* 948 */, 0x06D09A39B5926DB6LL /* 949 */, - 0x6F83AEB0317AC588LL /* 950 */, 0x01E6CA4A86381F21LL /* 951 */, - 0x66FF3462D19F3025LL /* 952 */, 0x72207C24DDFD3BFBLL /* 953 */, - 0x4AF6B6D3E2ECE2EBLL /* 954 */, 0x9C994DBEC7EA08DELL /* 955 */, - 0x49ACE597B09A8BC4LL /* 956 */, 0xB38C4766CF0797BALL /* 957 */, - 0x131B9373C57C2A75LL /* 958 */, 0xB1822CCE61931E58LL /* 959 */, - 0x9D7555B909BA1C0CLL /* 960 */, 0x127FAFDD937D11D2LL /* 961 */, - 0x29DA3BADC66D92E4LL /* 962 */, 0xA2C1D57154C2ECBCLL /* 963 */, - 0x58C5134D82F6FE24LL /* 964 */, 0x1C3AE3515B62274FLL /* 965 */, - 0xE907C82E01CB8126LL /* 966 */, 0xF8ED091913E37FCBLL /* 967 */, - 0x3249D8F9C80046C9LL /* 968 */, 0x80CF9BEDE388FB63LL /* 969 */, - 0x1881539A116CF19ELL /* 970 */, 0x5103F3F76BD52457LL /* 971 */, - 0x15B7E6F5AE47F7A8LL /* 972 */, 0xDBD7C6DED47E9CCFLL /* 973 */, - 0x44E55C410228BB1ALL /* 974 */, 0xB647D4255EDB4E99LL /* 975 */, - 0x5D11882BB8AAFC30LL /* 976 */, 0xF5098BBB29D3212ALL /* 977 */, - 0x8FB5EA14E90296B3LL /* 978 */, 0x677B942157DD025ALL /* 979 */, - 0xFB58E7C0A390ACB5LL /* 980 */, 0x89D3674C83BD4A01LL /* 981 */, - 0x9E2DA4DF4BF3B93BLL /* 982 */, 0xFCC41E328CAB4829LL /* 983 */, - 0x03F38C96BA582C52LL /* 984 */, 0xCAD1BDBD7FD85DB2LL /* 985 */, - 0xBBB442C16082AE83LL /* 986 */, 0xB95FE86BA5DA9AB0LL /* 987 */, - 0xB22E04673771A93FLL /* 988 */, 0x845358C9493152D8LL /* 989 */, - 0xBE2A488697B4541ELL /* 990 */, 0x95A2DC2DD38E6966LL /* 991 */, - 0xC02C11AC923C852BLL /* 992 */, 0x2388B1990DF2A87BLL /* 993 */, - 0x7C8008FA1B4F37BELL /* 994 */, 0x1F70D0C84D54E503LL /* 995 */, - 0x5490ADEC7ECE57D4LL /* 996 */, 0x002B3C27D9063A3ALL /* 997 */, - 0x7EAEA3848030A2BFLL /* 998 */, 0xC602326DED2003C0LL /* 999 */, - 0x83A7287D69A94086LL /* 1000 */, 0xC57A5FCB30F57A8ALL /* 1001 */, - 0xB56844E479EBE779LL /* 1002 */, 0xA373B40F05DCBCE9LL /* 1003 */, - 0xD71A786E88570EE2LL /* 1004 */, 0x879CBACDBDE8F6A0LL /* 1005 */, - 0x976AD1BCC164A32FLL /* 1006 */, 0xAB21E25E9666D78BLL /* 1007 */, - 0x901063AAE5E5C33CLL /* 1008 */, 0x9818B34448698D90LL /* 1009 */, - 0xE36487AE3E1E8ABBLL /* 1010 */, 0xAFBDF931893BDCB4LL /* 1011 */, - 0x6345A0DC5FBBD519LL /* 1012 */, 0x8628FE269B9465CALL /* 1013 */, - 0x1E5D01603F9C51ECLL /* 1014 */, 0x4DE44006A15049B7LL /* 1015 */, - 0xBF6C70E5F776CBB1LL /* 1016 */, 0x411218F2EF552BEDLL /* 1017 */, - 0xCB0C0708705A36A3LL /* 1018 */, 0xE74D14754F986044LL /* 1019 */, - 0xCD56D9430EA8280ELL /* 1020 */, 0xC12591D7535F5065LL /* 1021 */, - 0xC83223F1720AEF96LL /* 1022 */, 0xC3A0396F7363A51FLL /* 1023 */ -}; - -/* The following macro denotes that an optimization */ -/* for Alpha is required. It is used only for */ -/* optimization of time. Otherwise it does nothing. */ -#ifdef _LP64 -#define OPTIMIZE_FOR_LP64 -#endif - -/* NOTE that this code is NOT FULLY OPTIMIZED for any */ -/* machine. Assembly code might be much faster on some */ -/* machines, especially if the code is compiled with */ -/* gcc. */ - -/* The number of passes of the hash function. */ -/* Three passes are recommended. */ -/* Use four passes when you need extra security. */ -/* Must be at least three. */ -#define PASSES 3 - -#define T1 (table) -#define T2 (table+256) -#define T3 (table+(256*2)) -#define T4 (table+(256*3)) - -#define SAVE_ABC do { \ - aa = a; \ - bb = b; \ - cc = c; \ -} while (/*CONSTCOND*/0) - -#ifdef OPTIMIZE_FOR_LP64 -/* This is the official definition of round */ -#define ROUND(a,b,c,x,mul) do { \ - c ^= x; \ - a -= T1[((c)>>(0*8))&0xFF] ^ T2[((c)>>(2*8))&0xFF] ^ \ - T3[((c)>>(4*8))&0xFF] ^ T4[((c)>>(6*8))&0xFF] ; \ - b += T4[((c)>>(1*8))&0xFF] ^ T3[((c)>>(3*8))&0xFF] ^ \ - T2[((c)>>(5*8))&0xFF] ^ T1[((c)>>(7*8))&0xFF] ; \ - b *= mul; \ -} while (/*CONSTCOND*/ 0) -#else -/* This code works faster when compiled on 32-bit machines */ -/* (but works slower on Alpha) */ -#define ROUND(a,b,c,x,mul) do { \ - c ^= x; \ - a -= T1[(uint8_t)(c)] ^ \ - T2[(const uint8_t)(((uint32_t)(c))>>(2*8))] ^ \ - T3[(const uint8_t)((c)>>(4*8))] ^ \ - T4[(const uint8_t)(((uint32_t)((c)>>(4*8)))>>(2*8))] ; \ - b += T4[(uint8_t)(((uint32_t)(c))>>(1*8))] ^ \ - T3[(const uint8_t)(((uint32_t)(c))>>(3*8))] ^ \ - T2[(const uint8_t)(((uint32_t)((c)>>(4*8)))>>(1*8))] ^ \ - T1[(const uint8_t)(((uint32_t)((c)>>(4*8)))>>(3*8))]; \ - b *= mul; \ -} while (/*CONSTCOND*/0) -#endif - -#define PASS(a,b,c,mul) do { \ - ROUND(a,b,c,x0,mul); \ - ROUND(b,c,a,x1,mul); \ - ROUND(c,a,b,x2,mul); \ - ROUND(a,b,c,x3,mul); \ - ROUND(b,c,a,x4,mul); \ - ROUND(c,a,b,x5,mul); \ - ROUND(a,b,c,x6,mul); \ - ROUND(b,c,a,x7,mul); \ -} while (/*CONSTCOND*/ 0) - -#define KEY_SCHEDULE do { \ - x0 -= x7 ^ (uint64_t)0xA5A5A5A5A5A5A5A5LL; \ - x1 ^= x0; \ - x2 += x1; \ - x3 -= x2 ^ ((~x1)<<19); \ - x4 ^= x3; \ - x5 += x4; \ - x6 -= x5 ^ ((~x4)>>23); \ - x7 ^= x6; \ - x0 += x7; \ - x1 -= x0 ^ ((~x7)<<19); \ - x2 ^= x1; \ - x3 += x2; \ - x4 -= x3 ^ ((~x2)>>23); \ - x5 ^= x4; \ - x6 += x5; \ - x7 -= x6 ^ (uint64_t)0x0123456789ABCDEFLL; \ -} while (/*CONSTCOND*/ 0) - -#define FEEDFORWARD do { \ - a ^= aa; \ - b -= bb; \ - c += cc; \ -} while (/*CONSTCOND*/ 0) - -#ifdef OPTIMIZE_FOR_LP64 -/* The loop is unrolled: works better on Alpha */ -#define COMPRESS do { \ - SAVE_ABC; \ - PASS(a,b,c,5); \ - KEY_SCHEDULE; \ - PASS(c,a,b,7); \ - KEY_SCHEDULE; \ - PASS(b,c,a,9); \ - for (pass_no = 3; pass_no < PASSES; pass_no++) { \ - KEY_SCHEDULE; \ - PASS(a,b,c,9); \ - tmpa = a; a = c; c = b; b = tmpa; \ - } \ - FEEDFORWARD; \ -} while (/*CONSTCOND*/ 0) -#else -/* loop: works better on PC and Sun (smaller cache?) */ -#define COMPRESS do { \ - SAVE_ABC; \ - for (pass_no = 0; pass_no < PASSES; pass_no++) { \ - if (pass_no != 0) { \ - KEY_SCHEDULE; \ - } \ - PASS(a,b,c,(pass_no==0?5:pass_no==1?7:9)); \ - tmpa = a; a = c; c = b; b = tmpa; \ - } \ - FEEDFORWARD; \ -} while (/*CONSTCOND*/0) -#endif - -#define TIGER_COMPRESS_MACRO(str, state) do { \ - uint64_t a, b, c, tmpa; \ - uint64_t aa, bb, cc; \ - uint64_t x0, x1, x2, x3, x4, x5, x6, x7; \ - int pass_no; \ - \ - a = state[0]; \ - b = state[1]; \ - c = state[2]; \ - \ - x0 = str[0]; x1 = str[1]; x2 = str[2]; x3 = str[3]; \ - x4 = str[4]; x5 = str[5]; x6 = str[6]; x7 = str[7]; \ - \ - COMPRESS; \ - \ - state[0] = a; \ - state[1] = b; \ - state[2] = c; \ -} while (/*CONSTCOND*/ 0) - -#ifdef OPTIMIZE_FOR_LP64 -/* The compress function is inlined: works better on Alpha. */ -/* Still leaves the function above in the code, in case some other */ -/* module calls it directly. */ -#define tiger_compress(str, state) \ - TIGER_COMPRESS_MACRO(((const uint64_t*)(const void *)str), ((uint64_t*)(void *)state)) -#else -/* The compress function is a function. Requires smaller cache? */ -static void -tiger_compress(const uint64_t *str, uint64_t state[3]) -{ - TIGER_COMPRESS_MACRO(((const uint64_t*)str), ((uint64_t*)state)); -} -#endif - -/* weird function to format 8 raw bytes to 16 formatted hex chars */ -static void -sprint_uint64(char *buf, uint64_t val) -{ - static const char hexdigits[] = "0123456789abcdef"; - int indian = 1; - int i; - - for (i = 0; i < 8; ++i) { - if (IS_LITTLE_ENDIAN(indian)) { - buf[2 * (7 - i)] = hexdigits[(val >> (56 - 8 * i + 4)) & 15]; - buf[(2 * (7 - i)) + 1] = hexdigits[(val >> (56 - 8 * i)) & 15]; - } else { - buf[2 * i] = hexdigits[(val >> (56 - 8 * i + 4)) & 15]; - buf[(2 * i) + 1] = hexdigits[(val >> (56 - 8 * i)) & 15]; - } - } -} - -/* common function to initialise context */ -static void -initcontext(TIGER_CTX *ctx, uint8_t pad) -{ - (void) memset(ctx, 0x0, sizeof(*ctx)); - ctx->ctx[0] = 0x0123456789ABCDEFLL; - ctx->ctx[1] = 0xFEDCBA9876543210LL; - ctx->ctx[2] = 0xF096A5B4C3B2E187LL; - ctx->init = 1; - ctx->pad = pad; -} - -/* set the version number (0 is same as 1 for Tiger) */ -static int -setversion(TIGER_CTX *ctx, int version) -{ - switch(version) { - case 0: - case 1: - initcontext(ctx, 0x01); - break; - case 2: - initcontext(ctx, 0x80); - break; - default: - (void) fprintf(stderr, "unknown version %d\n", version); - return 0; - } - return 1; -} - -/*****************************************************************************/ - -void -TIGER_Init(TIGER_CTX *ctx) -{ - if (ctx) { - initcontext(ctx, 0x01); - } -} - -void -TIGER2_Init(TIGER_CTX *ctx) -{ - if (ctx) { - initcontext(ctx, 0x80); - } -} - -void -TIGER_Update(TIGER_CTX *ctx, const void *data, size_t length) -{ - const uint64_t *str = (const uint64_t *)data; - uint64_t i; - uint64_t j; - union { - uint8_t temp8[64]; - uint64_t temp64[8]; - } u; - int indian = 1; - - if (ctx == NULL || data == NULL) { - return; - } - for(i = length; i >= 64; i -= 64) { - if (IS_BIG_ENDIAN(indian)) { - for (j = 0; j < 64; j++) { - u.temp8[j ^ 7] = ((const uint8_t *)(const void *)str)[j]; - } - tiger_compress(u.temp64, ctx->ctx); - } else { - tiger_compress(str, ctx->ctx); - } - str += 8; - } - if (IS_BIG_ENDIAN(indian)) { - for (j = 0; j < i; j++) { - u.temp8[j ^ 7] = ((const uint8_t*)(const void *)str)[j]; - } - u.temp8[j ^ 7] = ctx->pad; - for (j++; j&7; j++) { - u.temp8[j ^ 7] = 0; - } - } else { - for (j = 0; j < i; j++) { - u.temp8[j] = ((const uint8_t*)(const void *)str)[j]; - } - u.temp8[j++] = ctx->pad; - for (; j&7; j++) { - u.temp8[j] = 0; - } - } - if (j > 56) { - for (; j < 64; j++) { - u.temp8[j] = 0; - } - tiger_compress(u.temp64, ctx->ctx); - j = 0; - } - for (; j < 56; j++) { - u.temp8[j] = 0; - } - ((uint64_t *)(void *)(&(u.temp8[56])))[0] = ((uint64_t)length) << 3; - tiger_compress(u.temp64, ctx->ctx); -} - -void -TIGER_Final(uint8_t *digest, TIGER_CTX *ctx) -{ - uint64_t le[3]; - int indian = 1; - int i; - - if (digest == NULL || ctx == NULL) { - return; - } - if (!ctx->init) { - TIGER_Init(ctx); - TIGER_Update(ctx, NULL, 0); - } - if (IS_LITTLE_ENDIAN(indian)) { - for (i = 0; i < 3; ++i) { - le[i] = (uint64_t)BSWAP64(ctx->ctx[i]); - } - (void) memcpy(digest, le, 3 * sizeof(le[0])); - } else { - (void) memcpy(digest, ctx->ctx, 3 * sizeof(ctx->ctx[0])); - } -} - -char * -TIGER_End(TIGER_CTX *ctx, char *buf) -{ - int i; - - if (ctx == NULL) { - return NULL; - } - if (buf == NULL && (buf = calloc(1, 49)) == NULL) { - return NULL; - } - if (!ctx->init) { - TIGER_Init(ctx); - TIGER_Update(ctx, NULL, 0); - } - for (i = 0; i < 3; ++i) { - sprint_uint64(buf + i * 16, ctx->ctx[i]); - } - buf[16 * i] = 0x0; - return buf; -} - -char * -TIGER_File(char *filename, char *buf, int version) -{ - TIGER_CTX ctx; - uint8_t buffer[BUFSIZ]; - ssize_t num; - int fd; - int oerrno; - - if (filename == NULL || buf == NULL || !setversion(&ctx, version)) { - return NULL; - } - if ((fd = open(filename, O_RDONLY)) < 0) { - return NULL; - } - while ((num = read(fd, buffer, sizeof(buffer))) > 0) { - TIGER_Update(&ctx, buffer, (size_t)num); - } - oerrno = errno; - close(fd); - errno = oerrno; - return (num < 0) ? NULL : TIGER_End(&ctx, buf); -} - -char * -TIGER_Data(const uint8_t *data, size_t len, char *buf, int version) -{ - TIGER_CTX ctx; - - if (data == NULL || buf == NULL || !setversion(&ctx, version)) { - return NULL; - } - TIGER_Update(&ctx, data, len); - return TIGER_End(&ctx, buf); -} diff --git a/security/libnetpgpverify/files/src/libdigest/tiger.h b/security/libnetpgpverify/files/src/libdigest/tiger.h deleted file mode 100644 index ff25cf949d3..00000000000 --- a/security/libnetpgpverify/files/src/libdigest/tiger.h +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 2005-2011 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef TIGER_H_ -#define TIGER_H_ - -#include <sys/types.h> - -#include <inttypes.h> - -#ifndef __BEGIN_DECLS -# if defined(__cplusplus) -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -# else -# define __BEGIN_DECLS -# define __END_DECLS -# endif -#endif - -__BEGIN_DECLS - -#define TIGER_DIGEST_LENGTH 24 -#define TIGER_DIGEST_STRING_LENGTH ((TIGER_DIGEST_LENGTH * 2) + 1) - -typedef struct TIGER_CTX { - uint64_t ctx[3]; - int init; - uint8_t pad; -} TIGER_CTX; - -void TIGER_Init(TIGER_CTX *); -void TIGER2_Init(TIGER_CTX *); -void TIGER_Update(TIGER_CTX *, const void *, size_t); -void TIGER_Final(uint8_t *, TIGER_CTX *); - -char *TIGER_End(TIGER_CTX *, char *); - -char *TIGER_File(char *, char *, int); -char *TIGER_Data(const uint8_t *, size_t, char *, int); - -__END_DECLS - -#endif diff --git a/security/libnetpgpverify/files/src/librsa/Makefile b/security/libnetpgpverify/files/src/librsa/Makefile deleted file mode 100644 index a60ebfd462f..00000000000 --- a/security/libnetpgpverify/files/src/librsa/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -LIB=netrsa -SRCS=rsa.c stubs.c -MKMAN=no -WARNS=4 -CPPFLAGS+=-I${.CURDIR}/../bn - -INCS=rsa.h -INCSDIR=/usr/include/netpgp - -.include <bsd.lib.mk> diff --git a/security/libnetpgpverify/files/src/librsa/libnetpgprsa.3 b/security/libnetpgpverify/files/src/librsa/libnetpgprsa.3 deleted file mode 100644 index 1862f03f50b..00000000000 --- a/security/libnetpgpverify/files/src/librsa/libnetpgprsa.3 +++ /dev/null @@ -1,113 +0,0 @@ -.\" $NetBSD: libnetpgprsa.3,v 1.2 2013/07/20 21:50:54 wiz Exp $ -.\" -.\" Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.Dd April 13, 2012 -.Dt LIBNETPGPRSA 3 -.Os -.Sh NAME -.Nm libnetpgprsa -.Nd BIGNUM library of multi-precision integers -.Sh LIBRARY -.Lb libnetpgprsa -.Sh SYNOPSIS -.In netpgp/rsa.h -.Ft RSA * -.Fo RSA_new -.Fa "void" -.Fc -.Ft int -.Fo RSA_size -.Fa "const RSA *rsa" -.Fc -.Ft void -.Fo RSA_free -.Fa "RSA *rsa" -.Fc -.Ft int -.Fo RSA_check_key -.Fa "RSA *rsa" -.Fc -.Ft RSA * -.Fo RSA_generate_key -.Fa "int num" "unsigned long e" "void (*callback)(int, int, void *)" "void *callbackarg" -.Fc -.Ft int -.Fo RSA_public_encrypt -.Fa "int siglen" "const uint8_t *signature" "uint8_t *to" "RSA *rsa" "int padding" -.Fc -.Ft int -.Fo RSA_private_encrypt -.Fa "int siglen" "const uint8_t *signature" "uint8_t *to" "RSA *rsa" "int padding" -.Fc -.Ft int -.Fo RSA_private_decrypt -.Fa "int siglen" "const uint8_t *signature" "uint8_t *to" "RSA *rsa" "int padding" -.Fc -.Pp -.Ft DSA * -.Fo DSA_new -.Fa "void" -.Fc -.Ft int -.Fo DSA_size -.Fa "const DSA *dsa" -.Fc -.Ft void -.Fo DSA_free -.Fa "DSA *dsa" -.Fc -.Ft DSA_SIG * -.Fo DSA_SIG_new -.Fa "void" -.Fc -.Ft void -.Fo DSA_SIG_free -.Fa "DSA_SIG *sig" -.Fc -.Ft int -.Fo DSA_do_verify -.Fa "const unsigned char *digest" "int digestlen" "DSA_SIG *sig" "DSA *dsa" -.Fc -.Ft int -.Fo DSA_do_sign -.Fa "const unsigned char *digest" "int digestlen" "DSA *dsa" -.Fc -.Sh DESCRIPTION -.Nm -is a small library which provides RSA signing, -encryption and decryption, and DSA signing. -RSA and DSA verification are provided by the -.Xr libnetpgpverify 3 -library. -.Sh SEE ALSO -.Xr libnetpgpbn 3 , -.Xr libnetpgpverify 3 -.Sh HISTORY -The -.Nm -library first appeared in -.Nx 7.0 . -.Sh AUTHORS -.An Alistair Crooks Aq Mt agc@NetBSD.org diff --git a/security/libnetpgpverify/files/src/librsa/rsa.c b/security/libnetpgpverify/files/src/librsa/rsa.c deleted file mode 100644 index d25ebb2a2b9..00000000000 --- a/security/libnetpgpverify/files/src/librsa/rsa.c +++ /dev/null @@ -1,696 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include <sys/types.h> -#include <sys/syslog.h> - -#ifdef _KERNEL -# include <sys/kmem.h> -# define logmessage log -#else -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# include <unistd.h> -#endif - -#include "misc.h" -#include "digest.h" -#include "rsa.h" - -#ifndef USE_ARG -#define USE_ARG(x) /*LINTED*/(void)&(x) -#endif - -#define RSA_MAX_MODULUS_BITS 16384 -#define RSA_SMALL_MODULUS_BITS 3072 -#define RSA_MAX_PUBEXP_BITS 64 /* exponent limit enforced for "large" modulus only */ - -static int -rsa_padding_check_none(uint8_t *to, int tlen, const uint8_t *from, int flen, int num) -{ - USE_ARG(num); - if (flen > tlen) { - printf("r too large\n"); - return -1; - } - (void) memset(to, 0x0, tlen - flen); - (void) memcpy(to + tlen - flen, from, flen); - return tlen; -} - -static int -lowlevel_rsa_private_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, RSA *rsa) -{ - BIGNUM *decbn; - BIGNUM *signedbn; - uint8_t *decbuf; - int nbytes; - int signc; - int signedbytes; - int r; - - decbuf = NULL; - r = -1; - decbn = BN_new(); - signedbn = BN_new(); - nbytes = BN_num_bytes(rsa->n); - decbuf = netpgp_allocate(1, nbytes); - /* add no padding */ - memcpy(decbuf, plain, plainc); - BN_bin2bn(decbuf, nbytes, decbn); - if (BN_cmp(decbn, rsa->n) >= 0) { - printf("decbn too big\n"); - goto err; - } - if (!BN_mod_exp(signedbn, decbn, rsa->d, rsa->n, NULL)) { - printf("bad mod_exp\n"); - goto err; - } - signedbytes = BN_num_bytes(signedbn); - signc = BN_bn2bin(signedbn, &encbuf[nbytes - signedbytes]); - memset(encbuf, 0x0, nbytes - signc); - r = nbytes; -err: - netpgp_deallocate(decbuf, nbytes); - BN_clear_free(decbn); - BN_clear_free(signedbn); - return r; -} - -static int -lowlevel_rsa_public_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, RSA *rsa) -{ - BIGNUM *decbn; - BIGNUM *encbn; - uint8_t *decbuf; - int nbytes; - int encc; - int r; - int i; - - r = -1; - decbn = BN_new(); - encbn = BN_new(); - nbytes = BN_num_bytes(rsa->n); - decbuf = netpgp_allocate(1, nbytes); - (void) memcpy(decbuf, plain, plainc); - if (BN_bin2bn(decbuf, nbytes, decbn) == NULL) { - printf("bin2bn failed\n"); - goto err; - } - if (BN_cmp(decbn, rsa->n) >= 0) { - printf("BN_cmp failed\n"); - goto err; - } - if (!BN_mod_exp(encbn, decbn, rsa->e, rsa->n, NULL)) { - printf("BN_mod_exp failed\n"); - goto err; - } - encc = BN_num_bytes(encbn); - i = BN_bn2bin(encbn, &encbuf[nbytes - encc]); - (void) memset(encbuf, 0x0, nbytes - i); - r = nbytes; -err: - if (decbuf) { - memset(decbuf, 0x0, nbytes); - netpgp_deallocate(decbuf, nbytes); - } - BN_clear_free(decbn); - BN_clear_free(encbn); - return r; -} - -static int -lowlevel_rsa_private_decrypt(int enclen, const unsigned char *encbuf, unsigned char *to, RSA *rsa) -{ - BIGNUM *encbn; - BIGNUM *decbn; - uint8_t *buf; - int nbytes; - int j; - int r; - - r = -1; - decbn = encbn = NULL; - buf = NULL; - if (BN_num_bits(rsa->n) > RSA_MAX_MODULUS_BITS) { - return -1; - } - if (BN_cmp(rsa->n, rsa->e) <= 0) { - return -1; - } - encbn = BN_new(); - decbn = BN_new(); - nbytes = BN_num_bytes(rsa->n); - buf = netpgp_allocate(1, nbytes); - if (enclen > nbytes) { - printf("bad enclen\n"); - goto err; - } - BN_bin2bn(encbuf, enclen, encbn); - if (BN_cmp(encbn, rsa->n) >= 0) { - printf("bad encbn\n"); - goto err; - } - BN_mod_exp(decbn, encbn, rsa->d, rsa->n, NULL); - j = BN_bn2bin(decbn, buf); - r = rsa_padding_check_none(to, nbytes, buf, j, nbytes); -err: - BN_clear_free(encbn); - BN_clear_free(decbn); - netpgp_deallocate(buf, nbytes); - return r; -} - -static int -lowlevel_rsa_public_decrypt(const uint8_t *encbuf, int enclen, uint8_t *dec, const rsa_pubkey_t *rsa) -{ - uint8_t *decbuf; - BIGNUM *decbn; - BIGNUM *encbn; - int decbytes; - int nbytes; - int r; - - nbytes = 0; - r = -1; - decbuf = NULL; - decbn = encbn = NULL; - if (BN_num_bits(rsa->n) > RSA_MAX_MODULUS_BITS) { - printf("rsa r modulus too large\n"); - goto err; - } - if (BN_cmp(rsa->n, rsa->e) <= 0) { - printf("rsa r bad n value\n"); - goto err; - } - if (BN_num_bits(rsa->n) > RSA_SMALL_MODULUS_BITS && - BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) { - printf("rsa r bad exponent limit\n"); - goto err; - } - if ((encbn = BN_new()) == NULL || - (decbn = BN_new()) == NULL || - (decbuf = netpgp_allocate(1, nbytes = BN_num_bytes(rsa->n))) == NULL) { - printf("allocation failure\n"); - goto err; - } - if (enclen > nbytes) { - printf("rsa r > mod len\n"); - goto err; - } - if (BN_bin2bn(encbuf, enclen, encbn) == NULL) { - printf("null encrypted BN\n"); - goto err; - } - if (BN_cmp(encbn, rsa->n) >= 0) { - printf("rsa r data too large for modulus\n"); - goto err; - } - if (BN_mod_exp(decbn, encbn, rsa->e, rsa->n, NULL) < 0) { - printf("BN_mod_exp < 0\n"); - goto err; - } - decbytes = BN_num_bytes(decbn); - (void) BN_bn2bin(decbn, decbuf); - if ((r = rsa_padding_check_none(dec, nbytes, decbuf, decbytes, 0)) < 0) { - printf("rsa r padding check failed\n"); - } -err: - BN_free(encbn); - BN_free(decbn); - if (decbuf != NULL) { - (void) memset(decbuf, 0x0, nbytes); - netpgp_deallocate(decbuf, nbytes); - } - return r; -} - -#if 0 -/** - @file rsa_make_key.c - RSA key generation, Tom St Denis -*/ - -/** - Create an RSA key - @param prng An active PRNG state - @param wprng The index of the PRNG desired - @param size The size of the modulus (key size) desired (octets) - @param e The "e" value (public key). e==65537 is a good choice - @param key [out] Destination of a newly created private key pair - @return CRYPT_OK if successful, upon error all allocated ram is freed -*/ -static int -rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) -{ - void *p, *q, *tmp1, *tmp2, *tmp3; - int err; - - LTC_ARGCHK(ltc_mp.name != NULL); - LTC_ARGCHK(key != NULL); - - if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) { - return CRYPT_INVALID_KEYSIZE; - } - - if ((e < 3) || ((e & 1) == 0)) { - return CRYPT_INVALID_ARG; - } - - if ((err = prng_is_valid(wprng)) != CRYPT_OK) { - return err; - } - - if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) { - return err; - } - - /* make primes p and q (optimization provided by Wayne Scott) */ - /* tmp3 = e */ - if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) { - goto errkey; - } - - /* make prime "p" */ - do { - if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK) { - goto errkey; - } - /* tmp1 = p-1 */ - if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { - goto errkey; - } - /* tmp2 = gcd(p-1, e) */ - if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { - goto errkey; - } - } while (mp_cmp_d( tmp2, 1) != 0); - /* while e divides p-1 */ - - /* make prime "q" */ - do { - if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) { - goto errkey; - } - /* tmp1 = q-1 */ - if ((err = mp_sub_d( q, 1, tmp1)) != CRYPT_OK) { - goto errkey; - } - /* tmp2 = gcd(q-1, e) */ - if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { - goto errkey; - } - } while (mp_cmp_d( tmp2, 1) != 0); - /* while e divides q-1 */ - - /* tmp1 = lcm(p-1, q-1) */ - /* tmp2 = p-1 */ - if ((err = mp_sub_d( p, 1, tmp2)) != CRYPT_OK) { - goto errkey; - } - /* tmp1 = q-1 (previous do/while loop) */ - /* tmp1 = lcm(p-1, q-1) */ - if ((err = mp_lcm( tmp1, tmp2, tmp1)) != CRYPT_OK) { - goto errkey; - } - - /* make key */ - if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { - goto errkey; - } - - /* key->e = e */ - if ((err = mp_set_int( key->e, e)) != CRYPT_OK) { - goto errkey; - } - /* key->d = 1/e mod lcm(p-1,q-1) */ - if ((err = mp_invmod( key->e, tmp1, key->d)) != CRYPT_OK) { - goto errkey; - } - /* key->N = pq */ - if ((err = mp_mul( p, q, key->N)) != CRYPT_OK) { - goto errkey; - } - - /* optimize for CRT now */ - /* find d mod q-1 and d mod p-1 */ - /* tmp1 = q-1 */ - if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { - goto errkey; - } - /* tmp2 = p-1 */ - if ((err = mp_sub_d( q, 1, tmp2)) != CRYPT_OK) { - goto errkey; - } - /* dP = d mod p-1 */ - if ((err = mp_mod( key->d, tmp1, key->dP)) != CRYPT_OK) { - goto errkey; - } - /* dQ = d mod q-1 */ - if ((err = mp_mod( key->d, tmp2, key->dQ)) != CRYPT_OK) { - goto errkey; - } - /* qP = 1/q mod p */ - if ((err = mp_invmod( q, p, key->qP)) != CRYPT_OK) { - got oerrkey; - } - - if ((err = mp_copy( p, key->p)) != CRYPT_OK) { - goto errkey; - } - if ((err = mp_copy( q, key->q)) != CRYPT_OK) { - goto errkey; - } - - /* set key type (in this case it's CRT optimized) */ - key->type = PK_PRIVATE; - - /* return ok and free temps */ - err = CRYPT_OK; - goto cleanup; -errkey: - mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); -cleanup: - mp_clear_multi(tmp3, tmp2, tmp1, p, q, NULL); - return err; -} -#endif - -#define HASHBUF_LEN 512 - -#define DSA_MAX_MODULUS_BITS 10000 - -static int -dsa_do_verify(const unsigned char *calculated, int dgst_len, const dsasig_t *sig, mpi_dsa_t *dsa) -{ - BIGNUM *M; - BIGNUM *W; - BIGNUM *t1; - int ret = -1; - int qbits; - - if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { - return 0; - } - M = W = t1 = NULL; - qbits = BN_num_bits(dsa->q); - switch(qbits) { - case 160: - case 224: - case 256: - /* openssl sources say these are the valid values */ - /* according to FIPS 186-3 */ - break; - default: - printf("dsa: bad # of Q bits\n"); - return 0; - } - if (BN_num_bits(dsa->p) > DSA_MAX_MODULUS_BITS) { - printf("dsa: p too large\n"); - return 0; - } - /* no love for SHA512? */ - if (dgst_len > SHA256_DIGEST_LENGTH) { - printf("dsa: digest too long\n"); - return 0; - } - ret = 0; - if ((M = BN_new()) == NULL || - (W = BN_new()) == NULL || - (t1 = BN_new()) == NULL) { - goto err; - } - if (BN_is_zero(sig->r) || - BN_is_negative(sig->r) || - BN_cmp(sig->r, dsa->q) >= 0) { - goto err; - } - if (BN_is_zero(sig->s) || - BN_is_negative(sig->s) || - BN_cmp(sig->s, dsa->q) >= 0) { - goto err; - } - if (BN_mod_inverse(W, sig->s, dsa->q, NULL) != MP_OKAY) { - goto err; - } - if (dgst_len > qbits / 8) { - dgst_len = qbits / 8; - } - if (BN_bin2bn(calculated, dgst_len, M) == NULL) { - goto err; - } - if (!BN_mod_mul(M, M, W, dsa->q, NULL)) { - goto err; - } - if (!BN_mod_mul(W, sig->r, W, dsa->q, NULL)) { - goto err; - } - if (!BN_mod_exp(dsa->p, t1, dsa->g, M, NULL)) { - goto err; - } - if (!BN_div(NULL, M, t1, dsa->q, NULL)) { - goto err; - } - ret = (BN_cmp(M, sig->r) == 0); -err: - if (M) { - BN_free(M); - } - if (W) { - BN_free(W); - } - if (t1) { - BN_free(t1); - } - return ret; -} - -/*************************************************************************/ - -int -RSA_size(const RSA *rsa) -{ - return (rsa == NULL) ? 0 : BN_num_bits(rsa->n); -} - -int -DSA_size(const DSA *dsa) -{ - return (dsa == NULL) ? 0 : BN_num_bits(dsa->p); -} - -unsigned -dsa_verify(const signature_t *signature, const dsa_pubkey_t *pubdsa, const uint8_t *calculated, size_t hash_length) -{ - mpi_dsa_t odsa; - dsasig_t osig; - unsigned qlen; - int ret; - - if (signature == NULL || pubdsa == NULL || calculated == NULL) { - return -1; - } - (void) memset(&osig, 0x0, sizeof(osig)); - (void) memset(&odsa, 0x0, sizeof(odsa)); - BN_copy(osig.r, signature->dsa.r); - BN_copy(osig.s, signature->dsa.s); - odsa.p = pubdsa->p; - odsa.q = pubdsa->q; - odsa.g = pubdsa->g; - odsa.pub_key = pubdsa->y; - if ((qlen = BN_num_bytes(odsa.q)) < hash_length) { - hash_length = qlen; - } - ret = dsa_do_verify(calculated, (int)hash_length, &signature->dsa, &odsa); - if (ret < 0) { - return 0; - } - BN_free(odsa.p); - BN_free(odsa.q); - BN_free(odsa.g); - BN_free(odsa.pub_key); - odsa.p = odsa.q = odsa.g = odsa.pub_key = NULL; - BN_free(osig.r); - BN_free(osig.s); - osig.r = osig.s = NULL; - return (unsigned)ret; -} - -RSA * -RSA_new(void) -{ - return netpgp_allocate(1, sizeof(RSA)); -} - -void -RSA_free(RSA *rsa) -{ - if (rsa) { - netpgp_deallocate(rsa, sizeof(*rsa)); - } -} - -int -RSA_check_key(RSA *rsa) -{ - BIGNUM *calcn; - int ret; - - ret = 0; - if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->n == NULL) { - return -1; - } - /* check that p and q are coprime, and that n = p*q. */ - if (!BN_is_prime(rsa->p, 1, NULL, NULL, NULL) || - !BN_is_prime(rsa->q, 1, NULL, NULL, NULL)) { - return 0; - } - calcn = BN_new(); - BN_mul(calcn, rsa->p, rsa->q, NULL); - if (BN_cmp(calcn, rsa->n) != 0) { - goto errout; - } - /* XXX - check that d*e = 1 mod (p-1*q-1) */ - ret = 1; -errout: - BN_clear_free(calcn); - return ret; -} - -RSA * -RSA_generate_key(int num, unsigned long e, void (*callback)(int,int,void *), void *cb_arg) -{ - /* STUBBED */ - USE_ARG(num); - USE_ARG(e); - USE_ARG(callback); - USE_ARG(cb_arg); - printf("RSA_generate_key stubbed\n"); - return RSA_new(); -} - -/* encrypt */ -int -RSA_public_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, RSA *rsa, int padding) -{ - USE_ARG(padding); - if (plain == NULL || encbuf == NULL || rsa == NULL) { - return -1; - } - return lowlevel_rsa_public_encrypt(plainc, plain, encbuf, rsa); -} - -/* decrypt */ -int -RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) -{ - USE_ARG(padding); - if (from == NULL || to == NULL || rsa == NULL) { - return -1; - } - return lowlevel_rsa_private_decrypt(flen, from, to, rsa); -} - -/* sign */ -int -RSA_private_encrypt(int plainc, const unsigned char *plain, unsigned char *encbuf, RSA *rsa, int padding) -{ - USE_ARG(padding); - if (plain == NULL || encbuf == NULL || rsa == NULL) { - return -1; - } - return lowlevel_rsa_private_encrypt(plainc, plain, encbuf, rsa); -} - -/* verify */ -int -RSA_public_decrypt(int enclen, const unsigned char *enc, unsigned char *dec, RSA *rsa, int padding) -{ - rsa_pubkey_t pub; - int ret; - - if (enc == NULL || dec == NULL || rsa == NULL) { - return 0; - } - USE_ARG(padding); - (void) memset(&pub, 0x0, sizeof(pub)); - pub.n = BN_dup(rsa->n); - pub.e = BN_dup(rsa->e); - ret = lowlevel_rsa_public_decrypt(enc, enclen, dec, &pub); - BN_free(pub.n); - BN_free(pub.e); - return ret; -} - -/***********************************************************************/ - -DSA * -DSA_new(void) -{ - return netpgp_allocate(1, sizeof(DSA)); -} - -void -DSA_free(DSA *dsa) -{ - if (dsa) { - netpgp_deallocate(dsa, sizeof(*dsa)); - } -} - -DSA_SIG * -DSA_SIG_new(void) -{ - return netpgp_allocate(1, sizeof(DSA_SIG)); -} - -void -DSA_SIG_free(DSA_SIG *sig) -{ - if (sig) { - netpgp_deallocate(sig, sizeof(*sig)); - } -} - -DSA_SIG * -DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) -{ - /* STUBBED */ - USE_ARG(dgst); - USE_ARG(dlen); - USE_ARG(dsa); - printf("DSA_do_sign stubbed\n"); - return DSA_SIG_new(); -} - -int -DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) -{ - if (dgst == NULL || dgst_len == 0 || sig == NULL || dsa == NULL) { - return -1; - } - return dsa_do_verify(dgst, dgst_len, sig, dsa); -} diff --git a/security/libnetpgpverify/files/src/librsa/rsa.h b/security/libnetpgpverify/files/src/librsa/rsa.h deleted file mode 100644 index 739c9756df4..00000000000 --- a/security/libnetpgpverify/files/src/librsa/rsa.h +++ /dev/null @@ -1,155 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef RSA_H_ -#define RSA_H_ 20120325 - -#include "bn.h" - -#ifndef __BEGIN_DECLS -# if defined(__cplusplus) -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -# else -# define __BEGIN_DECLS -# define __END_DECLS -# endif -#endif - -__BEGIN_DECLS - -typedef struct rsa_pubkey_t { - BIGNUM *n; /* RSA public modulus n */ - BIGNUM *e; /* RSA public encryption exponent e */ -} rsa_pubkey_t; - -typedef struct mpi_rsa_t { - int f1; /* openssl pad */ - long f2; /* openssl version */ - const void *f3; /* openssl method */ - void *f4; /* openssl engine */ - BIGNUM *n; - BIGNUM *e; - BIGNUM *d; - BIGNUM *p; - BIGNUM *q; - BIGNUM *dmp1; - BIGNUM *dmq1; - BIGNUM *iqmp; -} mpi_rsa_t; - -#define RSA mpi_rsa_t - -typedef struct dsa_pubkey_t { - BIGNUM *p; /* DSA public modulus n */ - BIGNUM *q; /* DSA public encryption exponent e */ - BIGNUM *g; - BIGNUM *y; -} dsa_pubkey_t; - -typedef struct mpi_dsa_t { - BIGNUM *p; - BIGNUM *q; - BIGNUM *g; - BIGNUM *y; - BIGNUM *x; - BIGNUM *pub_key; - BIGNUM *priv_key; -} mpi_dsa_t; - -#define DSA mpi_dsa_t - -typedef struct rsasig_t { - BIGNUM *sig; /* mpi which is actual signature */ -} rsasig_t; - -typedef struct dsasig_t { - BIGNUM *r; /* mpi which is actual signature */ - BIGNUM *s; /* mpi which is actual signature */ -} dsasig_t; - -#define DSA_SIG dsasig_t - -/* misc defs */ -#define RSA_NO_PADDING 3 - -#define SIGNETBSD_ID_SIZE 8 -#define SIGNETBSD_NAME_SIZE 128 - -#define RSA_PUBKEY_ALG 1 -#define DSA_PUBKEY_ALG 17 - -/* the public part of the key */ -typedef struct pubkey_t { - uint32_t version; /* key version - usually 4 */ - uint8_t id[SIGNETBSD_ID_SIZE]; /* binary id */ - char name[SIGNETBSD_NAME_SIZE]; /* name of identity - not necessary, but looks better */ - int64_t birthtime; /* time of creation of key */ - int64_t expiry; /* expiration time of the key */ - uint32_t validity; /* validity in days */ - uint32_t alg; /* pubkey algorithm - rsa/dss etc */ - rsa_pubkey_t rsa; /* specific RSA keys */ - dsa_pubkey_t dsa; /* specific DSA keys */ -} pubkey_t; - -/* signature details (for a specific file) */ -typedef struct signature_t { - uint32_t version; /* signature version number */ - uint32_t type; /* signature type value */ - int64_t birthtime; /* creation time of the signature */ - int64_t expiry; /* expiration time of the signature */ - uint8_t id[SIGNETBSD_ID_SIZE]; /* binary id */ - uint32_t key_alg; /* public key algorithm number */ - uint32_t hash_alg; /* hashing algorithm number */ - rsasig_t rsa; /* RSA signature */ - dsasig_t dsa; /* DSA signature */ - size_t v4_hashlen; /* length of hashed info */ - uint8_t *v4_hashed; /* hashed info */ - uint8_t hash2[2]; /* high 2 bytes of hashed value - for quick test */ - pubkey_t *signer; /* pubkey of signer */ -} signature_t; - -unsigned dsa_verify(const signature_t */*sig*/, const dsa_pubkey_t */*pubdsa*/, const uint8_t */*calc*/, size_t /*hashlen*/); - -RSA *RSA_new(void); -int RSA_size(const RSA */*rsa*/); -void RSA_free(RSA */*rsa*/); -int RSA_check_key(RSA */*rsa*/); -RSA *RSA_generate_key(int /*num*/, unsigned long /*e*/, void (*callback)(int,int,void *), void */*cb_arg*/); -int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); -int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); -int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); -int RSA_public_decrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa, int padding); - -DSA *DSA_new(void); -int DSA_size(const DSA */*rsa*/); -void DSA_free(DSA */*dsa*/); -DSA_SIG *DSA_SIG_new(void); -void DSA_SIG_free(DSA_SIG */*sig*/); -int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); -DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); - -__END_DECLS - -#endif diff --git a/security/libnetpgpverify/files/src/librsa/rsastubs.c b/security/libnetpgpverify/files/src/librsa/rsastubs.c deleted file mode 100644 index 2c36c7dd528..00000000000 --- a/security/libnetpgpverify/files/src/librsa/rsastubs.c +++ /dev/null @@ -1,83 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <pwd.h> - -#include "rsa.h" -#include "rsastubs.h" - -#ifndef USE_ARG -#define USE_ARG(x) /*LINTED*/(void)&(x) -#endif - -static int -pass_cb(char *buf, int size, int rwflag, void *u) -{ - char *passphrase; - char prompt[128]; - - USE_ARG(rwflag); - snprintf(prompt, sizeof(prompt), "\"%s\" passphrase: ", (char *)u); - if ((passphrase = getpass(prompt)) == NULL) { - return -1; - } - (void) memcpy(buf, passphrase, (size_t)size); - return (int)strlen(passphrase); -} - -RSA * -PEM_read_RSAPrivateKey(FILE *fp, RSA **x, pem_password_cb *cb, void *u) -{ - char phrase[128 + 1]; - RSA *rsa; - int cc; - -fprintf(stderr, "Stubbed PEM_read_RSAPrivateKey\n"); - USE_ARG(u); - if (cb == NULL) { - cb = pass_cb; - } - cc = (*cb)(phrase, sizeof(phrase), 0, u); - rsa = *x = RSA_new(); - USE_ARG(fp); - return rsa; -} - -DSA * -PEM_read_DSAPrivateKey(FILE *fp, DSA **x, pem_password_cb *cb, void *u) -{ - DSA *dsa; - - USE_ARG(u); - if (cb == NULL) { - cb = pass_cb; - } - dsa = *x = DSA_new(); - USE_ARG(fp); - return dsa; -} diff --git a/security/libnetpgpverify/files/src/librsa/rsastubs.h b/security/libnetpgpverify/files/src/librsa/rsastubs.h deleted file mode 100644 index e6f999c903e..00000000000 --- a/security/libnetpgpverify/files/src/librsa/rsastubs.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef RSASTUBS_H_ -#define RSASTUBS_H_ 20120412 - -#include "rsa.h" - -#ifndef __BEGIN_DECLS -# if defined(__cplusplus) -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -# else -# define __BEGIN_DECLS -# define __END_DECLS -# endif -#endif - -__BEGIN_DECLS - -typedef int pem_password_cb(char */*buf*/, int /*size*/, int /*rwflag*/, void */*userdata*/); - -RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **x, pem_password_cb *cb, void *u); -DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **x, pem_password_cb *cb, void *u); - -__END_DECLS - -#endif diff --git a/security/libnetpgpverify/files/src/libverify/Makefile b/security/libnetpgpverify/files/src/libverify/Makefile deleted file mode 100644 index 7b39520e233..00000000000 --- a/security/libnetpgpverify/files/src/libverify/Makefile +++ /dev/null @@ -1,71 +0,0 @@ -# $NetBSD: Makefile,v 1.1.1.1 2013/02/23 21:04:27 agc Exp $ - -PROG=netpgpv -SRCS=libverify.c b64.c pgpsum.c -SRCS+=digest.c tiger.c -SRCS+=bignum.c misc.c -SRCS+=rsaglue.c rsa.c -SRCS+=main.c -WARNS=5 -MKMAN=no -CPPFLAGS+=-I${.CURDIR}/../libbn -CPPFLAGS+=-I${.CURDIR}/../librsa -LDADD+=-lz -LDADD+=-lbz2 - -# XXX - debugging -#CPPFLAGS+=-g -O0 -#LDFLAGS+=-g -O0 -#CPPFLAGS+=-O3 -#LDFLAGS+=-O3 - -.PATH: ${.CURDIR} ${.CURDIR}/../libdigest ${.CURDIR}/../libverify ${.CURDIR}/../libbn ${.CURDIR}/../librsa - -.include <bsd.prog.mk> - -t: ${PROG} - ./${PROG} -c verify b.gpg > output16 - diff expected16 output16 - rm -f output16 - ./${PROG} -c verify a.gpg > output17 - diff expected17 output17 - rm -f output17 - ./${PROG} -c verify gpgsigned-a.gpg > output18 - diff expected18 output18 - rm -f output18 - ./${PROG} -c verify NetBSD-6.0_RC2_hashes.asc > output19 - diff expected19 output19 - rm -f output19 - ./${PROG} -c cat jj.asc > output20 - diff expected20 output20 - rm -f output20 - ./${PROG} < a.gpg > output21 - diff expected21 output21 - rm -f output21 - ./${PROG} < jj.asc > output22 - diff expected22 output22 - rm -f output22 - ./${PROG} < NetBSD-6.0_RC2_hashes.asc > output23 - diff expected23 output23 - rm -f output23 - ./${PROG} < b.gpg > output24 - diff expected24 output24 - rm -f output24 - ./${PROG} NetBSD-6.0_RC1_hashes.gpg > output25 - diff expected25 output25 - rm -f output25 - ./${PROG} < NetBSD-6.0_RC1_hashes.gpg > output26 - diff expected26 output26 - rm -f output26 - ./${PROG} < NetBSD-6.0_hashes.asc > output27 - diff expected27 output27 - rm -f output27 - ./${PROG} NetBSD-6.0_hashes.asc > output28 - diff expected28 output28 - rm -f output28 - ./${PROG} NetBSD-6.0_RC1_hashes_ascii.gpg > output29 - diff expected29 output29 - rm -f output29 - ./${PROG} < NetBSD-6.0_RC1_hashes_ascii.gpg > output30 - diff expected30 output30 - rm -f output30 diff --git a/security/libnetpgpverify/files/src/libverify/array.h b/security/libnetpgpverify/files/src/libverify/array.h deleted file mode 100644 index d5c19a98d67..00000000000 --- a/security/libnetpgpverify/files/src/libverify/array.h +++ /dev/null @@ -1,82 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef ARRAY_H_ -#define ARRAY_H_ 20120921 - -#ifndef PGPV_ARRAY -/* creates 2 unsigned vars called "name"c and "name"size in current scope */ -/* also creates an array called "name"s in current scope */ -#define PGPV_ARRAY(type, name) \ - unsigned name##c; unsigned name##vsize; type *name##s -#endif - -/* if this isn't part of a struct, need to specifically initialise things */ -#define ARRAY_INIT(name) do { \ - name##c = name##vsize = 0; \ - name##s = NULL; \ -} while(/*CONSTCOND*/0) - -/* check the array is big enough - if not, expand it by explicit amount */ -/* this is clunky, but there are bugs a-lurking */ -#define ARRAY_EXPAND_SIZED(name, mult, add) do { \ - if (name##c == name##vsize) { \ - void *_v; \ - char *_cv = NULL; \ - unsigned _ents; \ - _ents = (name##vsize * (mult)) + (add); \ - _cv = _v = realloc(name##s, _ents * sizeof(*name##s)); \ - if (_v == NULL) { \ - fprintf(stderr, "ARRAY_EXPAND - bad realloc\n"); \ - } else { \ - memset(&_cv[name##vsize * sizeof(*name##s)], \ - 0x0, (_ents - name##vsize) * sizeof(*name##s)); \ - name##s = _v; \ - name##vsize = _ents; \ - } \ - } \ -} while(/*CONSTCOND*/0) - -/* check the array is big enough - if not, expand it (size * 2) + 10 */ -#define ARRAY_EXPAND(name) ARRAY_EXPAND_SIZED(name, 2, 10) - -#define ARRAY_ELEMENT(name, num) name##s[num] -#define ARRAY_LAST(name) name##s[name##c - 1] -#define ARRAY_COUNT(name) name##c -#define ARRAY_SIZE(name) name##vsize -#define ARRAY_ARRAY(name) name##s - -#define ARRAY_APPEND(name, newel) do { \ - ARRAY_EXPAND(name); \ - ARRAY_COUNT(name) += 1; \ - ARRAY_LAST(name) = newel; \ -} while(/*CONSTCOND*/0) - -#define ARRAY_DELETE(name, num) do { \ - ARRAY_COUNT(name) -= 1; \ - memmove(&ARRAY_ELEMENT(name, num), &ARRAY_ELEMENT(name, num + 1), \ - (ARRAY_COUNT(name) - (num)) * sizeof(ARRAY_ELEMENT(name, 0))); \ -} while(/*CONSTCOND*/0) - -#endif diff --git a/security/libnetpgpverify/files/src/libverify/b64.c b/security/libnetpgpverify/files/src/libverify/b64.c deleted file mode 100644 index 50412dece7d..00000000000 --- a/security/libnetpgpverify/files/src/libverify/b64.c +++ /dev/null @@ -1,355 +0,0 @@ -/*********************************************************************\ - -MODULE NAME: b64.c - -AUTHOR: Bob Trower 08/04/01 - -PROJECT: Crypt Data Packaging - -COPYRIGHT: Copyright (c) Trantor Standard Systems Inc., 2001 - -NOTE: This source code may be used as you wish, subject to - the MIT license. See the LICENCE section below. - -DESCRIPTION: - This little utility implements the Base64 - Content-Transfer-Encoding standard described in - RFC1113 (http://www.faqs.org/rfcs/rfc1113.html). - - This is the coding scheme used by MIME to allow - binary data to be transferred by SMTP mail. - - Groups of 3 bytes from a binary stream are coded as - groups of 4 bytes in a text stream. - - The input stream is 'padded' with zeros to create - an input that is an even multiple of 3. - - A special character ('=') is used to denote padding so - that the stream can be decoded back to its exact size. - - Encoded output is formatted in lines which should - be a maximum of 72 characters to conform to the - specification. This program defaults to 72 characters, - but will allow more or less through the use of a - switch. The program enforces a minimum line size - of 4 characters. - - Example encoding: - - The stream 'ABCD' is 32 bits long. It is mapped as - follows: - - ABCD - - A (65) B (66) C (67) D (68) (None) (None) - 01000001 01000010 01000011 01000100 - - 16 (Q) 20 (U) 9 (J) 3 (D) 17 (R) 0 (A) NA (=) NA (=) - 010000 010100 001001 000011 010001 000000 000000 000000 - - - QUJDRA== - - Decoding is the process in reverse. A 'decode' lookup - table has been created to avoid string scans. - -DESIGN GOALS: Specifically: - Code is a stand-alone utility to perform base64 - encoding/decoding. It should be genuinely useful - when the need arises and it meets a need that is - likely to occur for some users. - Code acts as sample code to show the author's - design and coding style. - - Generally: - This program is designed to survive: - Everything you need is in a single source file. - It compiles cleanly using a vanilla ANSI C compiler. - It does its job correctly with a minimum of fuss. - The code is not overly clever, not overly simplistic - and not overly verbose. - Access is 'cut and paste' from a web page. - Terms of use are reasonable. - -VALIDATION: Non-trivial code is never without errors. This - file likely has some problems, since it has only - been tested by the author. It is expected with most - source code that there is a period of 'burn-in' when - problems are identified and corrected. That being - said, it is possible to have 'reasonably correct' - code by following a regime of unit test that covers - the most likely cases and regression testing prior - to release. This has been done with this code and - it has a good probability of performing as expected. - - Unit Test Cases: - - case 0:empty file: - CASE0.DAT -> -> - (Zero length target file created - on both encode and decode.) - - case 1:One input character: - CASE1.DAT A -> QQ== -> A - - case 2:Two input characters: - CASE2.DAT AB -> QUJD -> AB - - case 3:Three input characters: - CASE3.DAT ABC -> QUJD -> ABC - - case 4:Four input characters: - case4.dat ABCD -> QUJDRA== -> ABCD - - case 5:All chars from 0 to ff, linesize set to 50: - - AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIj - JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH - SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr - bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P - kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz - tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX - 2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7 - /P3+/w== - - case 6:Mime Block from e-mail: - (Data same as test case 5) - - case 7: Large files: - Tested 28 MB file in/out. - - case 8: Random Binary Integrity: - This binary program (b64.exe) was encoded to base64, - back to binary and then executed. - - case 9 Stress: - All files in a working directory encoded/decoded - and compared with file comparison utility to - ensure that multiple runs do not cause problems - such as exhausting file handles, tmp storage, etc. - - ------------- - - Syntax, operation and failure: - All options/switches tested. Performs as - expected. - - case 10: - No Args -- Shows Usage Screen - Return Code 1 (Invalid Syntax) - case 11: - One Arg (invalid) -- Shows Usage Screen - Return Code 1 (Invalid Syntax) - case 12: - One Arg Help (-?) -- Shows detailed Usage Screen. - Return Code 0 (Success -- help request is valid). - case 13: - One Arg Help (-h) -- Shows detailed Usage Screen. - Return Code 0 (Success -- help request is valid). - case 14: - One Arg (valid) -- Uses stdin/stdout (filter) - Return Code 0 (Sucess) - case 15: - Two Args (invalid file) -- shows system error. - Return Code 2 (File Error) - case 16: - Encode non-existent file -- shows system error. - Return Code 2 (File Error) - case 17: - Out of disk space -- shows system error. - Return Code 3 (File I/O Error) - - ------------- - - Compile/Regression test: - gcc compiled binary under Cygwin - Microsoft Visual Studio under Windows 2000 - Microsoft Version 6.0 C under Windows 2000 - -DEPENDENCIES: None - -LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated - documentation files (the "Software"), to deal in the - Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, - sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall - be included in all copies or substantial portions of the - Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY - KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS - OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -VERSION HISTORY: - Bob Trower 08/04/01 -- Create Version 0.00.00B - -\******************************************************************* */ - -#include <inttypes.h> -#include <stdio.h> -#include <stdlib.h> - -#include "b64.h" - -/* -** Translation Table as described in RFC1113 -*/ -static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/* -** Translation Table to decode (created by author) -*/ -static const char cd64[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; - -/* -** encodeblock -** -** encode 3 8-bit binary bytes as 4 '6-bit' characters -*/ -static void -encodeblock(uint8_t *wordin, uint8_t *wordout, int wordlen) -{ - wordout[0] = cb64[(unsigned)wordin[0] >> 2]; - wordout[1] = cb64[((unsigned)(wordin[0] & 0x03) << 4) | ((unsigned)(wordin[1] & 0xf0) >> 4)]; - wordout[2] = (uint8_t)(wordlen > 1) ? - cb64[((unsigned)(wordin[1] & 0x0f) << 2) | ((unsigned)(wordin[2] & 0xc0) >> 6)] : '='; - wordout[3] = (uint8_t)(wordlen > 2) ? cb64[wordin[2] & 0x3f] : '='; -} - -/* -** encode -** -** base64 encode a stream adding padding and line breaks as per spec. -*/ -int -b64encode(const char *in, const size_t insize, void *vp, size_t outsize, int linesize) -{ - const char *inp; - unsigned i; - uint8_t wordout[4]; - uint8_t wordin[3]; - char *out = vp; - char *outp; - int blocksout; - int wordlen; - - if (in == NULL || vp == NULL) { - return 0; - } - wordlen = 0; - for (blocksout = 0, inp = in, outp = out; (size_t)(inp - in) < insize && (size_t)(outp - out) < outsize;) { - for (wordlen = 0, i = 0; i < sizeof(wordin); i++) { - wordin[i] = (uint8_t) *inp++; - if ((size_t)(inp - in) <= insize) { - wordlen++; - } else { - wordin[i] = 0x0; - } - } - if (wordlen > 0) { - encodeblock(wordin, wordout, wordlen); - for (i = 0; i < sizeof(wordout) ; i++) { - *outp++ = wordout[i]; - } - blocksout++; - } - if (linesize > 0) { - if (blocksout >= (int)(linesize / sizeof(wordout)) || - (size_t)(inp - in) >= insize) { - if (blocksout) { - *outp++ = '\r'; - *outp++ = '\n'; - } - blocksout = 0; - } - } - } - return (int)(outp - out); -} - -/* -** decodeblock -** -** decode 4 '6-bit' characters into 3 8-bit binary bytes -*/ -static void -decodeblock(uint8_t wordin[4], uint8_t wordout[3]) -{ - wordout[0] = (uint8_t) ((unsigned)wordin[0] << 2 | (unsigned)wordin[1] >> 4); - wordout[1] = (uint8_t) ((unsigned)wordin[1] << 4 | (unsigned)wordin[2] >> 2); - wordout[2] = (uint8_t) (((wordin[2] << 6) & 0xc0) | wordin[3]); -} - -/* -** decode -** -** decode a base64 encoded stream discarding padding, line breaks and noise -*/ -int -b64decode(const char *in, const size_t insize, void *vp, size_t outsize) -{ - const char *inp; - unsigned wordlen; - unsigned i; - uint8_t wordout[3]; - uint8_t wordin[4]; - uint8_t v; - char *out = vp; - char *outp; - - if (in == NULL || vp == NULL) { - return 0; - } - for (inp = in, outp = out ; (size_t)(inp - in) < insize && (size_t)(outp - out) < outsize ; ) { - for (wordlen = 0, i = 0 ; i < sizeof(wordin) && (size_t)(inp - in) < insize ; i++) { - /* get a single character */ - for (v = 0; (size_t)(inp - in) <= insize && v == 0 ; ) { - if (*inp == '\r' && *(inp + 1) == '\n') { - inp += 2; - } else { - v = (uint8_t) *inp++; - v = (uint8_t) ((v < 43 || v > 122) ? 0 : cd64[v - 43]); - if (v) { - v = (uint8_t) ((v == '$') ? 0 : v - 61); - } - } - } - /* perhaps 0x0 pad */ - if ((size_t)(inp - in) <= insize) { - wordlen += 1; - if (v) { - wordin[i] = (uint8_t) (v - 1); - } - } else { - wordin[i] = 0x0; - } - } - if (wordlen > 0) { - decodeblock(wordin, wordout); - for (i = 0; i < wordlen - 1 ; i++) { - *outp++ = wordout[i]; - } - } - } - return (int)(outp - out); -} - -/* return the encoded size for n bytes input */ -int -b64_encsize(unsigned n) -{ - return ((4 * n) / 3) + 4; -} diff --git a/security/libnetpgpverify/files/src/libverify/b64.h b/security/libnetpgpverify/files/src/libverify/b64.h deleted file mode 100644 index e939857cbdb..00000000000 --- a/security/libnetpgpverify/files/src/libverify/b64.h +++ /dev/null @@ -1,32 +0,0 @@ -/*- - * Copyright (c) 2010 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef B64_H_ -#define B64_H_ 20091223 - -int b64encode(const char */*in*/, const size_t /*insize*/, void */*vp*/, size_t /*outsize*/, int /*linesize*/); -int b64decode(const char */*in*/, const size_t /*insize*/, void */*vp*/, size_t /*outsize*/); -int b64_encsize(unsigned /*n*/); - -#endif diff --git a/security/libnetpgpverify/files/src/libverify/dump.c b/security/libnetpgpverify/files/src/libverify/dump.c deleted file mode 100644 index 0c31b4b6b0d..00000000000 --- a/security/libnetpgpverify/files/src/libverify/dump.c +++ /dev/null @@ -1,88 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include <inttypes.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#ifndef isprint -#define isprint(x) ((x) >= ' ' && (x) <= '~') -#endif - -#define HEXDUMP_LINELEN 16 - -#ifndef PRIsize -#define PRIsize "z" -#endif - -/* show hexadecimal/ascii dump */ -static ssize_t -hexdump(const char *in, const size_t len, void *outvp, size_t size) -{ - size_t i; - char line[HEXDUMP_LINELEN + 1]; - char *out = (char *)outvp; - int o; - - for (i = 0, o = 0 ; i < len ; i++) { - if (i % HEXDUMP_LINELEN == 0) { - o += snprintf(&out[o], size - o, - "%.5" PRIsize "u | ", i); - } - o += snprintf(&out[o], size - o, "%.02x ", (uint8_t)in[i]); - line[i % HEXDUMP_LINELEN] = - (isprint((uint8_t)in[i])) ? in[i] : '.'; - if (i % HEXDUMP_LINELEN == HEXDUMP_LINELEN - 1) { - line[HEXDUMP_LINELEN] = 0x0; - o += snprintf(&out[o], size - o, " | %s\n", line); - } - } - if (i % HEXDUMP_LINELEN != 0) { - for ( ; i % HEXDUMP_LINELEN != 0 ; i++) { - o += snprintf(&out[o], size - o, " "); - line[i % HEXDUMP_LINELEN] = ' '; - } - line[HEXDUMP_LINELEN] = 0x0; - o += snprintf(&out[o], size - o, " | %s\n", line); - } - return (ssize_t)o; -} - -void dumpmem(void */*p*/, size_t /*size*/); - -/* just dump an area of memory to stdout */ -void -dumpmem(void *vp, size_t size) -{ - ssize_t cc; - uint8_t *p = (uint8_t *)vp; - char *buf; - - buf = calloc(1, size * 5); - cc = hexdump((const char *)p, size, buf, size * 5); - fprintf(stdout, "%.*s\n", (int)cc, buf); - free(buf); -} diff --git a/security/libnetpgpverify/files/src/libverify/libnetpgpverify.3 b/security/libnetpgpverify/files/src/libverify/libnetpgpverify.3 deleted file mode 100644 index 31b8035a4f3..00000000000 --- a/security/libnetpgpverify/files/src/libverify/libnetpgpverify.3 +++ /dev/null @@ -1,139 +0,0 @@ -.\" $NetBSD: libnetpgpverify.3,v 1.2 2013/07/20 21:50:54 wiz Exp $ -.\" -.\" Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.Dd October 21, 2012 -.Dt LIBNETPGPVERIFY 3 -.Os -.Sh NAME -.Nm libnetpgpverify -.Nd library to verify digital signatures -.Sh LIBRARY -.Lb libnetpgpverify -.Sh SYNOPSIS -.In netpgp/verify.h -.Ft int -.Fo pgpv_read_pubring -.Fa "pgpv_t *pgp" "const void *keyring" "ssize_t size" -.Fc -.Ft size_t -.Fo pgpv_verify -.Fa "pgpv_cursor_t *cursor" "pgpv_t *pgp" "const void *ptr" "ssize_t size" -.Fc -.Ft size_t -.Fo pgpv_get_verified -.Fa "pgpv_cursor_t *cursor" "size_t cookie " "char **ret" -.Fc -.Ft size_t -.Fo pgpv_get_entry -.Fa "pgpv_t *pgp" "unsigned ent" "char **ret" -.Fc -.Ft int -.Fo pgpv_close -.Fa "pgpv_t *pgp" -.Fc -.Sh DESCRIPTION -.Nm -is a small library which will verify a digital signature on a text or -binary document. -It has been kept deliberately small and only uses compression libraries -to function. -.Pp -PGP messages, including key rings, are made up of PGP packets, defined -in RFC 4880. -To match a digital signature, the public key of the signer must be -located in a public key ring. -This library has enough functionality to parse a pubkey keyring, -using -.Fn pgpv_read_pubring -to read the public keys of trusted identities, -and to read files or memory which has already been signed. -The -.Fn pgpv_verify -function is used to verify the signature, either on data, or on memory. -To signal to -.Fn pgpv_verify -to read a file and verify it, the -.Dv size -argument should be set to -.Dv -1 -whilst a positive size signals that the pointer value should be that -of signed memory. -.Fn pgpv_verify -returns a cookie if the ignature was verified, or 0 if it did not. -This cookie can subsequently be used to retrieve the data which -was verified. -.Pp -If the signature does match, then the file or memory can be considered as being -verified as being unmodified and unchanged, integrally sound. -.Pp -Signatures have validity dates on them, and it is possible for a signature to -have expired when it is being checked. -If for any reason the signature does not match, then the reason for not -verifying the signature will be stored in the -.Dv why -buffer in the -.Dv pgpv_cursor_t -structure. -.Pp -Occasionally, the memory or contents of the file which matched the signature -will be needed, rather than a boolean value of whether it was verified. -To do this, the -.Fn pgpv_get_verified -function is used. -Arguments to -.Fn pgpv_get_verified -are the cookie returned from the verification, and a buffer -allocated for the returned data and its size. -If an error occurs, or the signature is not verified, a zero value is returned -for the size. -.Nm -stores the starts of the data of all verified matches, and so the entry -number argument is the index of the occurrence of verification. -The first match will have an entry number of 0, the second 1, and so on. -.Pp -The -.Fn pgpv_close -function is used to clean up after all matching and verification has taken place. -It frees and de-allocates all resources used in the verification of the signature. -.Pp -The program used for signing may encode into base64 encoding, and it may also -use embedded compression to make the output smaller than it would otherwise be. -This is handled automatically by -.Nm -.Sh SEE ALSO -.Xr bn 3 , -.\" .Xr bzlib2 3 , -.Xr zlib 3 -.Sh STANDARDS -The -.Nm -utility is designed to conform to IETF RFC 4880. -.Sh HISTORY -The -.Nm -library first appeared in -.Nx 7.0 . -.Sh AUTHORS -.An Alistair Crooks Aq Mt agc@NetBSD.org diff --git a/security/libnetpgpverify/files/src/libverify/libverify.c b/security/libnetpgpverify/files/src/libverify/libverify.c deleted file mode 100644 index 754a8cc1f3d..00000000000 --- a/security/libnetpgpverify/files/src/libverify/libverify.c +++ /dev/null @@ -1,2366 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <sys/mman.h> - -#include <bzlib.h> -#include <err.h> -#include <inttypes.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include <zlib.h> - -#include "array.h" -#include "bn.h" -#include "b64.h" -#include "digest.h" -#include "pgpsum.h" -#include "rsa.h" -#include "verify.h" - -#ifndef USE_ARG -#define USE_ARG(x) /*LINTED*/(void)&(x) -#endif - -#define BITS_TO_BYTES(b) (((b) + (CHAR_BIT - 1)) / CHAR_BIT) - -/* packet types */ -#define SIGNATURE_PKT 2 -#define ONEPASS_SIGNATURE_PKT 4 -#define PUBKEY_PKT 6 -#define COMPRESSED_DATA_PKT 8 -#define MARKER_PKT 10 -#define LITDATA_PKT 11 -#define TRUST_PKT 12 -#define USERID_PKT 13 -#define PUB_SUBKEY_PKT 14 -#define USER_ATTRIBUTE_PKT 17 - -/* only allow certain packets at certain times */ -#define PUBRING_ALLOWED "\002\006\014\015\016\021" -#define SIGNATURE_ALLOWED "\002\004\010\013" - -/* actions to do on close */ -#define FREE_MEM 0x01 -#define UNMAP_MEM 0x02 - -/* types of pubkey we encounter */ -#define PUBKEY_RSA_ENCRYPT_OR_SIGN 1 -#define PUBKEY_RSA_ENCRYPT 2 -#define PUBKEY_RSA_SIGN 3 -#define PUBKEY_ELGAMAL_ENCRYPT 16 -#define PUBKEY_DSA 17 -#define PUBKEY_ELLIPTIC_CURVE 18 -#define PUBKEY_ECDSA 19 -#define PUBKEY_ELGAMAL_ENCRYPT_OR_SIGN 20 - -/* hash algorithm definitions */ -#define PGPV_HASH_MD5 1 -#define PGPV_HASH_SHA1 2 -#define PGPV_HASH_RIPEMD 3 -#define PGPV_HASH_SHA256 8 -#define PGPV_HASH_SHA384 9 -#define PGPV_HASH_SHA512 10 - -/* pubkey defs for bignums */ -#define RSA_N 0 -#define RSA_E 1 -#define DSA_P 0 -#define DSA_Q 1 -#define DSA_G 2 -#define DSA_Y 3 -#define ELGAMAL_P 0 -#define ELGAMAL_G 1 -#define ELGAMAL_Y 2 - -/* sesskey indices */ -#define RSA_SESSKEY_ENCRYPTED_M 0 -#define RSA_SESSKEY_M 1 -#define ELGAMAL_SESSKEY_G_TO_K 0 -#define ELGAMAL_SESSKEY_ENCRYPTED_M 1 - -/* seckey indices */ -#define RSA_SECKEY_D 0 -#define RSA_SECKEY_P 1 -#define RSA_SECKEY_Q 2 -#define RSA_SECKEY_U 3 -#define DSA_SECKEY_X 0 -#define ELGAMAL_SECKEY_X 0 - -/* signature mpi indices in bignumber array */ -#define RSA_SIG 0 -#define DSA_R 0 -#define DSA_S 1 -#define ELGAMAL_SIG_R 0 -#define ELGAMAL_SIG_S 1 - -/* signature types */ -#define SIGTYPE_BINARY_DOC 0x00 /* Signature of a binary document */ -#define SIGTYPE_TEXT 0x01 /* Signature of a canonical text document */ -#define SIGTYPE_STANDALONE 0x02 /* Standalone signature */ - -#define SIGTYPE_GENERIC_USERID 0x10 /* Generic certification of a User ID and Public Key packet */ -#define SIGTYPE_PERSONA_USERID 0x11 /* Persona certification of a User ID and Public Key packet */ -#define SIGTYPE_CASUAL_USERID 0x12 /* Casual certification of a User ID and Public Key packet */ -#define SIGTYPE_POSITIVE_USERID 0x13 /* Positive certification of a User ID and Public Key packet */ - -#define SIGTYPE_SUBKEY_BINDING 0x18 /* Subkey Binding Signature */ -#define SIGTYPE_PRIMARY_KEY_BINDING 0x19 /* Primary Key Binding Signature */ -#define SIGTYPE_DIRECT_KEY 0x1f /* Signature directly on a key */ - -#define SIGTYPE_KEY_REVOCATION 0x20 /* Key revocation signature */ -#define SIGTYPE_SUBKEY_REVOCATION 0x28 /* Subkey revocation signature */ -#define SIGTYPE_CERT_REVOCATION 0x30 /* Certification revocation signature */ - -#define SIGTYPE_TIMESTAMP_SIG 0x40 /* Timestamp signature */ -#define SIGTYPE_3RDPARTY 0x50 /* Third-Party Confirmation signature */ - -/* Forward declarations */ -static int read_all_packets(pgpv_t */*pgp*/, pgpv_mem_t */*mem*/, const char */*op*/); -static int read_binary_file(pgpv_t */*pgp*/, const char */*op*/, const char */*fmt*/, ...); -static int read_binary_memory(pgpv_t */*pgp*/, const char */*op*/, const void */*memory*/, size_t /*size*/); -static int pgpv_find_keyid(pgpv_t */*pgp*/, const char */*strkeyid*/, uint8_t */*keyid*/); - -/* read a file into the pgpv_mem_t struct */ -static int -read_file(pgpv_t *pgp, const char *f) -{ - struct stat st; - pgpv_mem_t *mem; - - ARRAY_EXPAND(pgp->areas); - ARRAY_COUNT(pgp->areas) += 1; - mem = &ARRAY_LAST(pgp->areas); - memset(mem, 0x0, sizeof(*mem)); - if ((mem->fp = fopen(f, "r")) == NULL) { - warn("can't read '%s'", f); - return 0; - } - fstat(fileno(mem->fp), &st); - mem->size = (size_t)st.st_size; - mem->mem = mmap(NULL, mem->size, PROT_READ, MAP_SHARED, fileno(mem->fp), 0); - mem->dealloc = UNMAP_MEM; - return 1; -} - -/* DTRT and free resources */ -static int -closemem(pgpv_mem_t *mem) -{ - switch(mem->dealloc) { - case FREE_MEM: - free(mem->mem); - mem->size = 0; - break; - case UNMAP_MEM: - munmap(mem->mem, mem->size); - fclose(mem->fp); - break; - } - return 1; -} - -/* make a reference to a memory area, and its offset */ -static void -make_ref(pgpv_t *pgp, uint8_t mement, pgpv_ref_t *ref) -{ - ref->mem = mement; - ref->offset = ARRAY_ELEMENT(pgp->areas, ref->mem).cc; - ref->vp = pgp; -} - -/* return the pointer we wanted originally */ -static uint8_t * -get_ref(pgpv_ref_t *ref) -{ - pgpv_mem_t *mem; - pgpv_t *pgp = (pgpv_t *)ref->vp;; - - mem = &ARRAY_ELEMENT(pgp->areas, ref->mem); - return &mem->mem[ref->offset]; -} - -#define IS_PARTIAL(x) ((x) >= 224 && (x) < 255) -#define DECODE_PARTIAL(x) (1 << ((x) & 0x1f)) - -#define PKT_LENGTH(m, off) \ - ((m[off] < 192) ? (m[off]) : \ - (m[off] < 224) ? ((m[off] - 192) << 8) + (m[off + 1]) + 192 : \ - (m[off + 1] << 24) | ((m[off + 2]) << 16) | ((m[off + 3]) << 8) | (m[off + 4])) - -#define PKT_LENGTH_LENGTH(m, off) \ - ((m[off] < 192) ? 1 : (m[off] < 224) ? 2 : 5) - -/* fix up partial body lengths, return new size */ -static size_t -fixup_partials(pgpv_t *pgp, uint8_t *p, size_t totlen, size_t filesize, size_t *cc) -{ - pgpv_mem_t *mem; - size_t partial; - size_t newcc; - - if (totlen > filesize) { - printf("fixup_partial: filesize %zu is less than encoded size %zu\n", filesize, totlen); - return 0; - } - ARRAY_EXPAND(pgp->areas); - ARRAY_COUNT(pgp->areas) += 1; - mem = &ARRAY_LAST(pgp->areas); - mem->size = totlen; - if ((mem->mem = calloc(1, mem->size + 5)) == NULL) { - printf("fixup_partial: can't allocate %zu length\n", totlen); - return 0; - } - newcc = 0; - mem->dealloc = FREE_MEM; - for (*cc = 0 ; *cc < totlen ; newcc += partial, *cc += partial + 1) { - if (IS_PARTIAL(p[*cc])) { - partial = DECODE_PARTIAL(p[*cc]); - memcpy(&mem->mem[newcc], &p[*cc + 1], partial); - } else { - partial = PKT_LENGTH(p, *cc); - *cc += PKT_LENGTH_LENGTH(p, *cc); - memcpy(&mem->mem[newcc], &p[*cc], partial); - newcc += partial; - *cc += partial; - break; - } - } - return newcc; -} - -/* get the weirdo packet length */ -static size_t -get_pkt_len(uint8_t newfmt, uint8_t *p, size_t filesize, int isprimary) -{ - size_t lenbytes; - size_t len; - - if (newfmt) { - if (IS_PARTIAL(*p)) { - if (!isprimary) { - /* for sub-packets, only 1, 2 or 4 byte sizes allowed */ - return ((*p - 192) << 8) + *(p + 1) + 192; - } - lenbytes = 1; - for (len = DECODE_PARTIAL(*p) ; IS_PARTIAL(p[len + lenbytes]) ; lenbytes++) { - len += DECODE_PARTIAL(p[len + lenbytes]); - } - len += get_pkt_len(newfmt, &p[len + lenbytes], filesize, 1); - return len; - } - return PKT_LENGTH(p, 0); - } else { - switch(*--p & 0x3) { - case 0: - return *(p + 1); - case 1: - return (*(p + 1) << 8) | *(p + 2); - case 2: - return (*(p + 1) << 24) | (*(p + 2) << 16) | (*(p + 3) << 8) | *(p + 4); - default: - return filesize; - } - } -} - -/* get the length of the packet length field */ -static unsigned -get_pkt_len_len(uint8_t newfmt, uint8_t *p, int isprimary) -{ - if (newfmt) { - if (IS_PARTIAL(*p)) { - return (isprimary) ? 1 : 2; - } - return PKT_LENGTH_LENGTH(p, 0); - } else { - switch(*--p & 0x3) { - case 0: - return 1; - case 1: - return 2; - case 2: - return 4; - default: - return 0; - } - } -} - -/* copy the 32bit integer in memory in network order */ -static unsigned -fmt_32(uint8_t *p, uint32_t a) -{ - a = htonl(a); - memcpy(p, &a, sizeof(a)); - return sizeof(a); -} - -/* copy the 16bit integer in memory in network order */ -static unsigned -fmt_16(uint8_t *p, uint16_t a) -{ - a = htons(a); - memcpy(p, &a, sizeof(a)); - return sizeof(a); -} - -/* format a binary string in memory */ -static size_t -fmt_binary(char *s, size_t size, const uint8_t *bin, unsigned len) -{ - unsigned i; - size_t cc; - - for (cc = 0, i = 0 ; i < len && cc < size ; i++) { - cc += snprintf(&s[cc], size - cc, "%02x", bin[i]); - } - return cc; -} - -/* format an mpi into memory */ -static unsigned -fmt_binary_mpi(pgpv_bignum_t *mpi, uint8_t *p, size_t size) -{ - unsigned bytes; - BIGNUM *bn; - - bytes = BITS_TO_BYTES(mpi->bits); - if ((size_t)bytes + 2 + 1 > size) { - warn("truncated mpi"); - return 0; - } - bn = (BIGNUM *)mpi->bn; - if (bn == NULL || BN_is_zero(bn)) { - fmt_32(p, 0); - return 2 + 1; - } - fmt_16(p, mpi->bits); - BN_bn2bin(bn, &p[2]); - return bytes + 2; -} - -/* dump an mpi value onto stdout */ -static size_t -fmt_mpi(char *s, size_t size, pgpv_bignum_t *bn, const char *name, int pbits) -{ - size_t cc; - char *buf; - - cc = snprintf(s, size, "%s=", name); - if (pbits) { - cc += snprintf(&s[cc], size - cc, "[%u bits] ", bn->bits); - } - buf = BN_bn2hex(bn->bn); - cc += snprintf(&s[cc], size - cc, "%s\n", buf); - free(buf); - return cc; -} - -#define ALG_IS_RSA(alg) (((alg) == PUBKEY_RSA_ENCRYPT_OR_SIGN) || \ - ((alg) == PUBKEY_RSA_ENCRYPT) || \ - ((alg) == PUBKEY_RSA_SIGN)) - -#define ALG_IS_DSA(alg) ((alg) == PUBKEY_DSA) - -/* format key mpis into memory */ -static unsigned -fmt_key_mpis(pgpv_pubkey_t *pubkey, uint8_t *buf, size_t size) -{ - size_t cc; - - cc = 0; - buf[cc++] = pubkey->version; - cc += fmt_32(&buf[cc], (uint32_t)pubkey->birth); - buf[cc++] = pubkey->keyalg; - switch(pubkey->keyalg) { - case PUBKEY_RSA_ENCRYPT_OR_SIGN: - case PUBKEY_RSA_ENCRYPT: - case PUBKEY_RSA_SIGN: - cc += fmt_binary_mpi(&pubkey->bn[RSA_N], &buf[cc], size - cc); - cc += fmt_binary_mpi(&pubkey->bn[RSA_E], &buf[cc], size - cc); - break; - case PUBKEY_DSA: - cc += fmt_binary_mpi(&pubkey->bn[DSA_P], &buf[cc], size - cc); - cc += fmt_binary_mpi(&pubkey->bn[DSA_Q], &buf[cc], size - cc); - cc += fmt_binary_mpi(&pubkey->bn[DSA_G], &buf[cc], size - cc); - cc += fmt_binary_mpi(&pubkey->bn[DSA_Y], &buf[cc], size - cc); - break; - default: - cc += fmt_binary_mpi(&pubkey->bn[ELGAMAL_P], &buf[cc], size - cc); - cc += fmt_binary_mpi(&pubkey->bn[ELGAMAL_G], &buf[cc], size - cc); - cc += fmt_binary_mpi(&pubkey->bn[ELGAMAL_Y], &buf[cc], size - cc); - break; - } - return (unsigned)cc; -} - -/* calculate the fingerprint, RFC 4880, section 12.2 */ -static int -pgpv_calc_fingerprint(pgpv_fingerprint_t *fingerprint, pgpv_pubkey_t *pubkey) -{ - digest_t fphash; - uint16_t cc; - uint8_t ch = 0x99; - uint8_t buf[8192 + 2 + 1]; - uint8_t len[2]; - - memset(&fphash, 0x0, sizeof(fphash)); - if (pubkey->version == 4) { - /* v4 keys */ - fingerprint->hashalg = digest_get_alg("sha1"); - digest_init(&fphash, (unsigned)fingerprint->hashalg); - cc = fmt_key_mpis(pubkey, buf, sizeof(buf)); - digest_update(&fphash, &ch, 1); - fmt_16(len, cc); - digest_update(&fphash, len, 2); - digest_update(&fphash, buf, cc); - fingerprint->len = digest_final(fingerprint->v, &fphash); - return 1; - } - if (ALG_IS_RSA(pubkey->keyalg)) { - /* v3 keys are RSA */ - fingerprint->hashalg = digest_get_alg("md5"); - digest_init(&fphash, (unsigned)fingerprint->hashalg); - if (pubkey->bn[RSA_N].bn && pubkey->bn[RSA_E].bn) { - cc = fmt_binary_mpi(&pubkey->bn[RSA_N], buf, sizeof(buf)); - digest_update(&fphash, &buf[2], cc - 2); - cc = fmt_binary_mpi(&pubkey->bn[RSA_E], buf, sizeof(buf)); - digest_update(&fphash, &buf[2], cc - 2); - fingerprint->len = digest_final(fingerprint->v, &fphash); - return 1; - } - } - if (pubkey->bn[RSA_N].bn) { - if ((cc = fmt_binary_mpi(&pubkey->bn[RSA_N], buf, sizeof(buf))) >= PGPV_KEYID_LEN) { - memcpy(fingerprint->v, &buf[cc - PGPV_KEYID_LEN], PGPV_KEYID_LEN); - fingerprint->len = PGPV_KEYID_LEN; - return 1; - } - } - /* exhausted all avenues, really */ - memset(fingerprint->v, 0xff, fingerprint->len = PGPV_KEYID_LEN); - return 1; -} - -/* format a fingerprint into memory */ -static size_t -fmt_fingerprint(char *s, size_t size, pgpv_fingerprint_t *fingerprint, const char *name) -{ - unsigned i; - size_t cc; - - cc = snprintf(s, size, "%s ", name); - for (i = 0 ; i < fingerprint->len ; i++) { - cc += snprintf(&s[cc], size - cc, "%02hhx%s", - fingerprint->v[i], (i % 2 == 1) ? " " : ""); - } - cc += snprintf(&s[cc], size - cc, "\n"); - return cc; -} - -/* calculate keyid from a pubkey */ -static int -pgpv_calc_keyid(pgpv_pubkey_t *key) -{ - pgpv_calc_fingerprint(&key->fingerprint, key); - memcpy(key->keyid, &key->fingerprint.v[key->fingerprint.len - PGPV_KEYID_LEN], PGPV_KEYID_LEN); - return 1; -} - -/* convert a hex string to a 64bit key id (in big endian byte order */ -static void -str_to_keyid(const char *s, uint8_t *keyid) -{ - uint64_t u64; - - u64 = (uint64_t)strtoull(s, NULL, 16); - u64 = ((u64 & 0x00000000000000FFUL) << 56) | - ((u64 & 0x000000000000FF00UL) << 40) | - ((u64 & 0x0000000000FF0000UL) << 24) | - ((u64 & 0x00000000FF000000UL) << 8) | - ((u64 & 0x000000FF00000000UL) >> 8) | - ((u64 & 0x0000FF0000000000UL) >> 24) | - ((u64 & 0x00FF000000000000UL) >> 40) | - ((u64 & 0xFF00000000000000UL) >> 56); - memcpy(keyid, &u64, PGPV_KEYID_LEN); -} - -#define PKT_ALWAYS_ON 0x80 -#define PKT_NEWFMT_MASK 0x40 -#define PKT_NEWFMT_TAG_MASK 0x3f -#define PKT_OLDFMT_TAG_MASK 0x3c - -#define SUBPKT_CRITICAL_MASK 0x80 -#define SUBPKT_TAG_MASK 0x7f - -#define SUBPKT_SIG_BIRTH 2 -#define SUBPKT_SIG_EXPIRY 3 -#define SUBPKT_EXPORT_CERT 4 -#define SUBPKT_TRUST_SIG 5 -#define SUBPKT_REGEXP 6 -#define SUBPKT_REVOCABLE 7 -#define SUBPKT_KEY_EXPIRY 9 -#define SUBPKT_BWD_COMPAT 10 -#define SUBPKT_PREF_SYMMETRIC_ALG 11 -#define SUBPKT_REVOCATION_KEY 12 -#define SUBPKT_ISSUER 16 -#define SUBPKT_NOTATION 20 -#define SUBPKT_PREF_HASH_ALG 21 -#define SUBPKT_PREF_COMPRESS_ALG 22 -#define SUBPKT_KEY_SERVER_PREFS 23 -#define SUBPKT_PREF_KEY_SERVER 24 -#define SUBPKT_PRIMARY_USER_ID 25 -#define SUBPKT_POLICY_URI 26 -#define SUBPKT_KEY_FLAGS 27 -#define SUBPKT_SIGNER_ID 28 -#define SUBPKT_REVOCATION_REASON 29 -#define SUBPKT_FEATURES 30 -#define SUBPKT_SIGNATURE_TARGET 31 -#define SUBPKT_EMBEDDED_SIGNATURE 32 - -#define UNCOMPRESSED 0 -#define ZIP_COMPRESSION 1 -#define ZLIB_COMPRESSION 2 -#define BZIP2_COMPRESSION 3 - -/* get a 16 bit integer, in host order */ -static uint16_t -get_16(uint8_t *p) -{ - uint16_t u16; - - memcpy(&u16, p, sizeof(u16)); - return ntohs(u16); -} - -/* get a 32 bit integer, in host order */ -static uint32_t -get_32(uint8_t *p) -{ - uint32_t u32; - - memcpy(&u32, p, sizeof(u32)); - return ntohl(u32); -} - -#define HOURSECS (int64_t)(60 * 60) -#define DAYSECS (int64_t)(24 * 60 * 60) -#define MONSECS (int64_t)(30 * DAYSECS) -#define YEARSECS (int64_t)(365 * DAYSECS) - -/* format (human readable) time into memory */ -static size_t -fmt_time(char *s, size_t size, const char *header, int64_t n, const char *trailer, int relative) -{ - struct tm tm; - time_t elapsed; - time_t now; - time_t t; - size_t cc; - - t = (time_t)n; - now = time(NULL); - elapsed = now - t; - gmtime_r(&t, &tm); - cc = snprintf(s, size, "%s%04d-%02d-%02d", header, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - if (relative) { - cc += snprintf(&s[cc], size - cc, " (%lldy %lldm %lldd %lldh %s)", - llabs((long long)elapsed / YEARSECS), - llabs(((long long)elapsed % YEARSECS) / MONSECS), - llabs(((long long)elapsed % MONSECS) / DAYSECS), - llabs(((long long)elapsed % DAYSECS) / HOURSECS), - (now > t) ? "ago" : "ahead"); - } - cc += snprintf(&s[cc], size - cc, "%s", trailer); - return cc; -} - -/* dump key mpis to stdout */ -static void -print_key_mpis(pgpv_bignum_t *v, uint8_t keyalg) -{ - char s[8192]; - - switch(keyalg) { - case PUBKEY_RSA_ENCRYPT_OR_SIGN: - case PUBKEY_RSA_ENCRYPT: - case PUBKEY_RSA_SIGN: - fmt_mpi(s, sizeof(s), &v[RSA_N], "rsa.n", 1); - printf("%s", s); - fmt_mpi(s, sizeof(s), &v[RSA_E], "rsa.e", 1); - printf("%s", s); - break; - case PUBKEY_ELGAMAL_ENCRYPT: - fmt_mpi(s, sizeof(s), &v[ELGAMAL_P], "elgamal.p", 1); - printf("%s", s); - fmt_mpi(s, sizeof(s), &v[ELGAMAL_Y], "elgamal.y", 1); - printf("%s", s); - break; - case PUBKEY_DSA: - fmt_mpi(s, sizeof(s), &v[DSA_P], "dsa.p", 1); - printf("%s", s); - fmt_mpi(s, sizeof(s), &v[DSA_Q], "dsa.q", 1); - printf("%s", s); - fmt_mpi(s, sizeof(s), &v[DSA_G], "dsa.g", 1); - printf("%s", s); - fmt_mpi(s, sizeof(s), &v[DSA_Y], "dsa.y", 1); - printf("%s", s); - break; - default: - printf("hi, unusual keyalg %u\n", keyalg); - break; - } -} - -/* get an mpi, including 2 byte length */ -static int -get_mpi(pgpv_bignum_t *mpi, uint8_t *p, size_t pktlen, size_t *off) -{ - size_t bytes; - - mpi->bits = get_16(p); - if ((bytes = (size_t)BITS_TO_BYTES(mpi->bits)) > pktlen) { - return 0; - } - *off += sizeof(mpi->bits); - mpi->bn = BN_bin2bn(&p[sizeof(mpi->bits)], (int)bytes, NULL); - *off += bytes; - return 1; -} - -/* read mpis in signature */ -static int -read_signature_mpis(pgpv_sigpkt_t *sigpkt, uint8_t *p, size_t pktlen) -{ - size_t off; - - off = 0; - switch(sigpkt->sig.keyalg) { - case PUBKEY_RSA_ENCRYPT_OR_SIGN: - case PUBKEY_RSA_SIGN: - case PUBKEY_RSA_ENCRYPT: - if (!get_mpi(&sigpkt->sig.bn[RSA_SIG], p, pktlen, &off)) { - printf("sigpkt->version %d, rsa sig weird\n", sigpkt->sig.version); - return 0; - } - break; - case PUBKEY_DSA: - case PUBKEY_ECDSA: - case PUBKEY_ELGAMAL_ENCRYPT_OR_SIGN: /* deprecated */ - if (!get_mpi(&sigpkt->sig.bn[DSA_R], p, pktlen, &off) || - !get_mpi(&sigpkt->sig.bn[DSA_S], &p[off], pktlen, &off)) { - printf("sigpkt->version %d, dsa/elgamal sig weird\n", sigpkt->sig.version); - return 0; - } - break; - default: - printf("weird type of sig! %d\n", sigpkt->sig.keyalg); - return 0; - } - return 1; -} - -/* add the signature sub packet to the signature packet */ -static int -add_subpacket(pgpv_sigpkt_t *sigpkt, uint8_t tag, uint8_t *p, uint16_t len) -{ - pgpv_sigsubpkt_t subpkt; - - memset(&subpkt, 0x0, sizeof(subpkt)); - subpkt.s.size = len; - subpkt.critical = 0; - subpkt.tag = tag; - subpkt.s.data = p; - ARRAY_APPEND(sigpkt->subpkts, subpkt); - return 1; -} - -/* read the subpackets in the signature */ -static int -read_sig_subpackets(pgpv_sigpkt_t *sigpkt, uint8_t *p, size_t pktlen) -{ - pgpv_sigsubpkt_t subpkt; - const int is_subpkt = 0; - unsigned lenlen; - unsigned i; - uint8_t *start; - - start = p; - for (i = 0 ; (unsigned)(p - start) < sigpkt->subslen ; i++) { - memset(&subpkt, 0x0, sizeof(subpkt)); - subpkt.s.size = get_pkt_len(1, p, 0, is_subpkt); - lenlen = get_pkt_len_len(1, p, is_subpkt); - if (lenlen > pktlen) { - printf("weird lenlen %u\n", lenlen); - return 0; - } - p += lenlen; - subpkt.critical = (*p & SUBPKT_CRITICAL_MASK); - subpkt.tag = (*p & SUBPKT_TAG_MASK); - p += 1; - switch(subpkt.tag) { - case SUBPKT_SIG_BIRTH: - sigpkt->sig.birth = (int64_t)get_32(p); - break; - case SUBPKT_SIG_EXPIRY: - sigpkt->sig.expiry = (int64_t)get_32(p); - break; - case SUBPKT_KEY_EXPIRY: - sigpkt->sig.keyexpiry = (int64_t)get_32(p); - break; - case SUBPKT_ISSUER: - sigpkt->sig.signer = p; - break; - case SUBPKT_SIGNER_ID: - sigpkt->sig.signer = p; - break; - case SUBPKT_TRUST_SIG: - sigpkt->sig.trustsig = *p; - break; - case SUBPKT_REGEXP: - sigpkt->sig.regexp = (char *)(void *)p; - break; - case SUBPKT_REVOCABLE: - sigpkt->sig.revocable = *p; - break; - case SUBPKT_PREF_SYMMETRIC_ALG: - sigpkt->sig.pref_symm_alg = *p; - break; - case SUBPKT_REVOCATION_KEY: - sigpkt->sig.revoke_sensitive = (*p & 0x40); - sigpkt->sig.revoke_alg = p[1]; - sigpkt->sig.revoke_fingerprint = &p[2]; - break; - case SUBPKT_NOTATION: - sigpkt->sig.notation = *p; - break; - case SUBPKT_PREF_HASH_ALG: - sigpkt->sig.pref_hash_alg = *p; - break; - case SUBPKT_PREF_COMPRESS_ALG: - sigpkt->sig.pref_compress_alg = *p; - break; - case SUBPKT_PREF_KEY_SERVER: - sigpkt->sig.pref_key_server = (char *)(void *)p; - break; - case SUBPKT_KEY_SERVER_PREFS: - sigpkt->sig.key_server_modify = *p; - break; - case SUBPKT_KEY_FLAGS: - sigpkt->sig.type_key = *p; - break; - case SUBPKT_PRIMARY_USER_ID: - sigpkt->sig.primary_userid = *p; - break; - case SUBPKT_POLICY_URI: - sigpkt->sig.policy = (char *)(void *)p; - break; - case SUBPKT_FEATURES: - sigpkt->sig.features = (char *)(void *)p; - break; - case SUBPKT_REVOCATION_REASON: - sigpkt->sig.revoked = *p++ + 1; - sigpkt->sig.why_revoked = (char *)(void *)p; - break; - default: - printf("Ignoring unusual/reserved signature subpacket %d\n", subpkt.tag); - break; - } - subpkt.s.data = p; - p += subpkt.s.size - 1; - ARRAY_APPEND(sigpkt->subpkts, subpkt); - } - return 1; -} - -/* parse signature packet */ -static int -read_sigpkt(pgpv_t *pgp, uint8_t mement, pgpv_sigpkt_t *sigpkt, uint8_t *p, size_t pktlen) -{ - unsigned lenlen; - uint8_t *base; - - make_ref(pgp, mement, &sigpkt->sig.hashstart); - base = p; - switch(sigpkt->sig.version = *p++) { - case 2: - case 3: - if ((lenlen = *p++) != 5) { - printf("read_sigpkt: hashed length not 5\n"); - return 0; - } - sigpkt->sig.hashlen = lenlen; - /* put birthtime into a subpacket */ - sigpkt->sig.type = *p++; - add_subpacket(sigpkt, SUBPKT_SIG_BIRTH, p, sizeof(uint32_t)); - sigpkt->sig.birth = (int64_t)get_32(p); - p += sizeof(uint32_t); - sigpkt->sig.signer = p; - add_subpacket(sigpkt, SUBPKT_SIGNER_ID, p, PGPV_KEYID_LEN); - p += PGPV_KEYID_LEN; - sigpkt->sig.keyalg = *p++; - sigpkt->sig.hashalg = *p++; - sigpkt->sig.hash2 = p; - if (!read_signature_mpis(sigpkt, sigpkt->sig.mpi = p + 2, pktlen)) { - printf("read_sigpkt: can't read sigs v3\n"); - return 0; - } - break; - case 4: - sigpkt->sig.type = *p++; - sigpkt->sig.keyalg = *p++; - sigpkt->sig.hashalg = *p++; - sigpkt->subslen = get_16(p); - p += sizeof(sigpkt->subslen); - if (!read_sig_subpackets(sigpkt, p, pktlen)) { - printf("read_sigpkt: can't read sig subpackets, v4\n"); - return 0; - } - if (!sigpkt->sig.signer) { - sigpkt->sig.signer = get_ref(&sigpkt->sig.hashstart) + 16; - } - p += sigpkt->subslen; - sigpkt->sig.hashlen = (unsigned)(p - base); - sigpkt->unhashlen = get_16(p); - p += sizeof(sigpkt->unhashlen) + sigpkt->unhashlen; - sigpkt->sig.hash2 = p; - if (!read_signature_mpis(sigpkt, sigpkt->sig.mpi = p + 2, pktlen)) { - printf("read_sigpkt: can't read sigs, v4\n"); - return 0; - } - break; - default: - printf("read_sigpkt: unusual signature version (%u)\n", sigpkt->sig.version); - break; - } - return 1; -} - - -/* this parses compressed data, decompresses it, and calls the parser again */ -static int -read_compressed(pgpv_t *pgp, pgpv_compress_t *compressed, uint8_t *p, size_t len) -{ - pgpv_mem_t *unzmem; - bz_stream bz; - z_stream z; - int ok = 0; - - compressed->compalg = *p; - compressed->s.size = len; - if ((compressed->s.data = calloc(1, len)) == NULL) { - printf("read_compressed: can't allocate %zu length\n", len); - return 0; - } - switch(compressed->compalg) { - case UNCOMPRESSED: - printf("not implemented %d compression yet\n", compressed->compalg); - return 0; - default: - break; - } - ARRAY_EXPAND(pgp->areas); - ARRAY_COUNT(pgp->areas) += 1; - unzmem = &ARRAY_LAST(pgp->areas); - unzmem->size = len * 10; - unzmem->dealloc = FREE_MEM; - if ((unzmem->mem = calloc(1, unzmem->size)) == NULL) { - printf("read_compressed: calloc failed!\n"); - return 0; - } - switch(compressed->compalg) { - case ZIP_COMPRESSION: - case ZLIB_COMPRESSION: - memset(&z, 0x0, sizeof(z)); - z.next_in = p + 1; - z.avail_in = (unsigned)(len - 1); - z.total_in = (unsigned)(len - 1); - z.next_out = unzmem->mem; - z.avail_out = (unsigned)unzmem->size; - z.total_out = (unsigned)unzmem->size; - break; - case BZIP2_COMPRESSION: - memset(&bz, 0x0, sizeof(bz)); - bz.avail_in = (unsigned)(len - 1); - bz.next_in = (char *)(void *)p + 1; - bz.next_out = (char *)(void *)unzmem->mem; - bz.avail_out = (unsigned)unzmem->size; - break; - } - switch(compressed->compalg) { - case ZIP_COMPRESSION: - ok = (inflateInit2(&z, -15) == Z_OK); - break; - case ZLIB_COMPRESSION: - ok = (inflateInit(&z) == Z_OK); - break; - case BZIP2_COMPRESSION: - ok = (BZ2_bzDecompressInit(&bz, 1, 0) == BZ_OK); - break; - } - if (!ok) { - printf("read_compressed: initialisation failed!\n"); - return 0; - } - switch(compressed->compalg) { - case ZIP_COMPRESSION: - case ZLIB_COMPRESSION: - ok = (inflate(&z, Z_FINISH) == Z_STREAM_END); - unzmem->size = z.total_out; - break; - case BZIP2_COMPRESSION: - ok = (BZ2_bzDecompress(&bz) == BZ_STREAM_END); - unzmem->size = ((uint64_t)bz.total_out_hi32 << 32) | bz.total_out_lo32; - break; - } - if (!ok) { - printf("read_compressed: inflate failed!\n"); - return 0; - } - return 1; -} - -/* parse one pass signature packet */ -static int -read_onepass_sig(pgpv_onepass_t *onepasspkt, uint8_t *mem) -{ - onepasspkt->version = mem[0]; - onepasspkt->type = mem[1]; - onepasspkt->hashalg = mem[2]; - onepasspkt->keyalg = mem[3]; - memcpy(onepasspkt->keyid, &mem[4], sizeof(onepasspkt->keyid)); - onepasspkt->nested = mem[12]; - return 1; -} - -/* parse public key packet */ -static int -read_pubkey(pgpv_pubkey_t *pubkey, uint8_t *mem, size_t pktlen, int pbn) -{ - size_t off; - - off = 0; - pubkey->version = mem[off++]; - pubkey->birth = get_32(&mem[off]); - off += 4; - if (pubkey->version == 2 || pubkey->version == 3) { - pubkey->expiry = get_16(&mem[off]) * DAYSECS; - off += 2; - } - if ((pubkey->keyalg = mem[off++]) == 0) { - pubkey->keyalg = PUBKEY_RSA_ENCRYPT_OR_SIGN; - printf("got unusual pubkey keyalg %u\n", mem[off - 1]); - } - switch(pubkey->keyalg) { - case PUBKEY_RSA_ENCRYPT_OR_SIGN: - case PUBKEY_RSA_ENCRYPT: - case PUBKEY_RSA_SIGN: - if (!get_mpi(&pubkey->bn[RSA_N], &mem[off], pktlen, &off) || - !get_mpi(&pubkey->bn[RSA_E], &mem[off], pktlen, &off)) { - return 0; - } - break; - case PUBKEY_ELGAMAL_ENCRYPT: - case PUBKEY_ELGAMAL_ENCRYPT_OR_SIGN: - if (!get_mpi(&pubkey->bn[ELGAMAL_P], &mem[off], pktlen, &off) || - !get_mpi(&pubkey->bn[ELGAMAL_Y], &mem[off], pktlen, &off)) { - return 0; - } - break; - case PUBKEY_DSA: - if (!get_mpi(&pubkey->bn[DSA_P], &mem[off], pktlen, &off) || - !get_mpi(&pubkey->bn[DSA_Q], &mem[off], pktlen, &off) || - !get_mpi(&pubkey->bn[DSA_G], &mem[off], pktlen, &off) || - !get_mpi(&pubkey->bn[DSA_Y], &mem[off], pktlen, &off)) { - return 0; - } - break; - default: - printf("hi, different type of pubkey here %u\n", pubkey->keyalg); - break; - } - if (pbn) { - print_key_mpis(pubkey->bn, pubkey->keyalg); - } - return 1; -} - -/* parse a user attribute */ -static int -read_userattr(pgpv_userattr_t *userattr, uint8_t *p, size_t pktlen) -{ - pgpv_string_t subattr; - const int is_subpkt = 0; - const int indian = 1; - unsigned lenlen; - uint16_t imagelen; - size_t cc; - - userattr->len = pktlen; - for (cc = 0 ; cc < pktlen ; cc += subattr.size + lenlen + 1) { - subattr.size = get_pkt_len(1, p, 0, is_subpkt); - lenlen = get_pkt_len_len(1, p, is_subpkt); - if (lenlen > pktlen) { - printf("weird lenlen %u\n", lenlen); - return 0; - } - p += lenlen; - if (*p++ != 1) { - printf("image type (%u) != 1. weird packet\n", *(p - 1)); - } - memcpy(&imagelen, p, sizeof(imagelen)); - if (!*(const char *)(const void *)&indian) { - /* big endian - byteswap length */ - imagelen = (((unsigned)imagelen & 0xff) << 8) | (((unsigned)imagelen >> 8) & 0xff); - } - subattr.data = p + 3; - p += subattr.size; - ARRAY_APPEND(userattr->subattrs, subattr); - } - return 1; -} - -#define LITDATA_BINARY 'b' -#define LITDATA_TEXT 't' -#define LITDATA_UTF8 'u' - -/* parse literal packet */ -static int -read_litdata(pgpv_t *pgp, pgpv_litdata_t *litdata, uint8_t *p, size_t size) -{ - size_t cc; - - cc = 0; - switch(litdata->format = p[cc++]) { - case LITDATA_BINARY: - case LITDATA_TEXT: - case LITDATA_UTF8: - litdata->namelen = 0; - break; - default: - printf("weird litdata format %u\n", litdata->format); - break; - } - litdata->namelen = p[cc++]; - litdata->filename = &p[cc]; - cc += litdata->namelen; - litdata->secs = get_32(&p[cc]); - cc += 4; - litdata->s.data = &p[cc]; - litdata->len = litdata->s.size = size - cc; - litdata->mem = ARRAY_COUNT(pgp->areas) - 1; - litdata->offset = cc; - return 1; -} - -/* parse a single packet */ -static int -read_pkt(pgpv_t *pgp, pgpv_mem_t *mem) -{ - const int isprimary = 1; - pgpv_pkt_t pkt; - pgpv_mem_t *newmem; - unsigned lenlen; - uint8_t ispartial; - size_t size; - - memset(&pkt, 0x0, sizeof(pkt)); - pkt.tag = mem->mem[mem->cc++]; - if (!(pkt.tag & PKT_ALWAYS_ON)) { - printf("BAD PACKET - bit 7 not 1, offset %zu!\n", mem->cc - 1); - } - pkt.newfmt = (pkt.tag & PKT_NEWFMT_MASK); - pkt.tag = (pkt.newfmt) ? - (pkt.tag & PKT_NEWFMT_TAG_MASK) : - (((unsigned)pkt.tag & PKT_OLDFMT_TAG_MASK) >> 2); - ispartial = (pkt.newfmt && IS_PARTIAL(mem->mem[mem->cc])); - pkt.s.size = get_pkt_len(pkt.newfmt, &mem->mem[mem->cc], mem->size - mem->cc, isprimary); - lenlen = get_pkt_len_len(pkt.newfmt, &mem->mem[mem->cc], isprimary); - pkt.offset = mem->cc; - mem->cc += lenlen; - pkt.mement = (uint8_t)(mem - ARRAY_ARRAY(pgp->areas)); - pkt.s.data = &mem->mem[mem->cc]; - if (strchr(mem->allowed, pkt.tag) == NULL) { - printf("packet %d not allowed for operation %s\n", pkt.tag, pgp->op); - return 0; - } - size = pkt.s.size; - if (ispartial) { - pkt.s.size = fixup_partials(pgp, &mem->mem[mem->cc - lenlen], pkt.s.size, mem->size, &size); - newmem = &ARRAY_LAST(pgp->areas); - pkt.mement = (uint8_t)(newmem - ARRAY_ARRAY(pgp->areas)); - pkt.s.data = newmem->mem; - size -= 1; - } - switch(pkt.tag) { - case SIGNATURE_PKT: - if (!read_sigpkt(pgp, pkt.mement, &pkt.u.sigpkt, pkt.s.data, pkt.s.size)) { - return 0; - } - break; - case ONEPASS_SIGNATURE_PKT: - read_onepass_sig(&pkt.u.onepass, pkt.s.data); - break; - case PUBKEY_PKT: - case PUB_SUBKEY_PKT: - break; - case LITDATA_PKT: - read_litdata(pgp, &pkt.u.litdata, pkt.s.data, pkt.s.size); - break; - case TRUST_PKT: - pkt.u.trust.level = pkt.s.data[0]; - pkt.u.trust.amount = pkt.s.data[1]; - break; - case USERID_PKT: - pkt.u.userid.size = pkt.s.size; - pkt.u.userid.data = pkt.s.data; - break; - case COMPRESSED_DATA_PKT: - read_compressed(pgp, &pkt.u.compressed, pkt.s.data, pkt.s.size); - ARRAY_APPEND(pgp->pkts, pkt); - read_all_packets(pgp, &ARRAY_LAST(pgp->areas), pgp->op); - break; - case USER_ATTRIBUTE_PKT: - read_userattr(&pkt.u.userattr, pkt.s.data, pkt.s.size); - break; - default: - printf("hi, need to implement %d, offset %zu\n", pkt.tag, mem->cc); - break; - } - mem->cc += size; - if (pkt.tag != COMPRESSED_DATA_PKT) { - /* compressed was added earlier to preserve pkt ordering */ - ARRAY_APPEND(pgp->pkts, pkt); - } - return 1; -} - -/* checks the tag type of a packet */ -static int -pkt_is(pgpv_t *pgp, int wanted) -{ - return (ARRAY_ELEMENT(pgp->pkts, pgp->pkt).tag == wanted); -} - -/* checks the packet is a signature packet, and the signature type is the expected one */ -static int -pkt_sigtype_is(pgpv_t *pgp, int wanted) -{ - if (!pkt_is(pgp, SIGNATURE_PKT)) { - return 0; - } - return (ARRAY_ELEMENT(pgp->pkts, pgp->pkt).u.sigpkt.sig.type == wanted); -} - -/* check for expected type of packet, and move to the next */ -static int -pkt_accept(pgpv_t *pgp, int expected) -{ - int got; - - if ((got = ARRAY_ELEMENT(pgp->pkts, pgp->pkt).tag) == expected) { - pgp->pkt += 1; - return 1; - } - printf("problem at token %zu, expcted %d, got %d\n", pgp->pkt, expected, got); - return 0; -} - -/* recognise signature (and trust) packet */ -static int -recog_signature(pgpv_t *pgp, pgpv_signature_t *signature) -{ - if (!pkt_is(pgp, SIGNATURE_PKT)) { - printf("recog_signature: not a signature packet\n"); - return 0; - } - memcpy(signature, &ARRAY_ELEMENT(pgp->pkts, pgp->pkt).u.sigpkt.sig, sizeof(*signature)); - pgp->pkt += 1; - if (pkt_is(pgp, TRUST_PKT)) { - pkt_accept(pgp, TRUST_PKT); - } - return 1; -} - -/* recognise user id packet */ -static int -recog_userid(pgpv_t *pgp, pgpv_signed_userid_t *userid) -{ - pgpv_signature_t signature; - pgpv_pkt_t *pkt; - - memset(userid, 0x0, sizeof(*userid)); - if (!pkt_is(pgp, USERID_PKT)) { - printf("recog_userid: not %d\n", USERID_PKT); - return 0; - } - pkt = &ARRAY_ELEMENT(pgp->pkts, pgp->pkt); - userid->userid.size = pkt->s.size; - userid->userid.data = pkt->s.data; - pgp->pkt += 1; - while (pkt_is(pgp, SIGNATURE_PKT)) { - if (!recog_signature(pgp, &signature)) { - printf("recog_userid: can't recognise signature/trust\n"); - return 0; - } - ARRAY_APPEND(userid->sigs, signature); - if (signature.primary_userid) { - userid->primary_userid = signature.primary_userid; - } - if (signature.revoked) { - userid->revoked = signature.revoked; - } - } - return 1; -} - -/* recognise user attributes packet */ -static int -recog_userattr(pgpv_t *pgp, pgpv_signed_userattr_t *userattr) -{ - pgpv_signature_t signature; - - memset(userattr, 0x0, sizeof(*userattr)); - if (!pkt_is(pgp, USER_ATTRIBUTE_PKT)) { - printf("recog_userattr: not %d\n", USER_ATTRIBUTE_PKT); - return 0; - } - userattr->userattr = ARRAY_ELEMENT(pgp->pkts, pgp->pkt).u.userattr; - pgp->pkt += 1; - while (pkt_is(pgp, SIGNATURE_PKT)) { - if (!recog_signature(pgp, &signature)) { - printf("recog_userattr: can't recognise signature/trust\n"); - return 0; - } - ARRAY_APPEND(userattr->sigs, signature); - if (signature.revoked) { - userattr->revoked = signature.revoked; - } - } - return 1; -} - -/* recognise a sub key */ -static int -recog_subkey(pgpv_t *pgp, pgpv_signed_subkey_t *subkey) -{ - pgpv_signature_t signature; - pgpv_pkt_t *pkt; - - pkt = &ARRAY_ELEMENT(pgp->pkts, pgp->pkt); - memset(subkey, 0x0, sizeof(*subkey)); - read_pubkey(&subkey->subkey, pkt->s.data, pkt->s.size, 0); - pgp->pkt += 1; - if (pkt_sigtype_is(pgp, SIGTYPE_KEY_REVOCATION) || - pkt_sigtype_is(pgp, SIGTYPE_SUBKEY_REVOCATION) || - pkt_sigtype_is(pgp, SIGTYPE_CERT_REVOCATION)) { - recog_signature(pgp, &signature); - subkey->revoc_self_sig = signature; - } - do { - if (!pkt_is(pgp, SIGNATURE_PKT)) { - printf("recog_subkey: not signature packet at %zu\n", pgp->pkt); - return 0; - } - if (!recog_signature(pgp, &signature)) { - printf("recog_subkey: bad signature/trust at %zu\n", pgp->pkt); - return 0; - } - ARRAY_APPEND(subkey->sigs, signature); - if (signature.keyexpiry) { - /* XXX - check it's a good key expiry */ - subkey->subkey.expiry = signature.keyexpiry; - } - } while (pkt_is(pgp, SIGNATURE_PKT)); - return 1; -} - -/* use a sparse map for the text strings here to save space */ -static const char *keyalgs[] = { - "[Unknown]", - "RSA (Encrypt or Sign)", - "RSA (Encrypt Only)", - "RSA (Sign Only)", - "Elgamal (Encrypt Only)", - "DSA", - "Elliptic Curve", - "ECDSA", - "Elgamal (Encrypt or Sign)" -}; - -#define MAX_KEYALG 21 - -static const char *keyalgmap = "\0\01\02\03\0\0\0\0\0\0\0\0\0\0\0\0\04\05\06\07\010\011"; - -/* return human readable name for key algorithm */ -static const char * -fmtkeyalg(uint8_t keyalg) -{ - return keyalgs[(uint8_t)keyalgmap[(keyalg >= MAX_KEYALG) ? 0 : keyalg]]; -} - -/* return the number of bits in the public key */ -static unsigned -numkeybits(const pgpv_pubkey_t *pubkey) -{ - switch(pubkey->keyalg) { - case PUBKEY_RSA_ENCRYPT_OR_SIGN: - case PUBKEY_RSA_ENCRYPT: - case PUBKEY_RSA_SIGN: - return pubkey->bn[RSA_N].bits; - case PUBKEY_DSA: - case PUBKEY_ECDSA: - return BITS_TO_BYTES(pubkey->bn[DSA_Q].bits) * 64; - case PUBKEY_ELGAMAL_ENCRYPT: - case PUBKEY_ELGAMAL_ENCRYPT_OR_SIGN: - return pubkey->bn[ELGAMAL_P].bits; - default: - return 0; - } -} - -/* print a public key */ -static size_t -fmt_pubkey(char *s, size_t size, pgpv_pubkey_t *pubkey, const char *leader) -{ - size_t cc; - - cc = snprintf(s, size, "%s %u/%s ", leader, numkeybits(pubkey), fmtkeyalg(pubkey->keyalg)); - cc += fmt_binary(&s[cc], size - cc, pubkey->keyid, PGPV_KEYID_LEN); - cc += fmt_time(&s[cc], size - cc, " ", pubkey->birth, "", 0); - if (pubkey->expiry) { - cc += fmt_time(&s[cc], size - cc, " [Expiry ", pubkey->birth + pubkey->expiry, "]", 0); - } - cc += snprintf(&s[cc], size - cc, "\n"); - cc += fmt_fingerprint(&s[cc], size - cc, &pubkey->fingerprint, "fingerprint: "); - return cc; -} - -/* we add 1 to revocation value to denote compromised */ -#define COMPROMISED (0x02 + 1) - -/* format a userid - used to order the userids when formatting */ -static size_t -fmt_userid(char *s, size_t size, pgpv_primarykey_t *primary, uint8_t u) -{ - pgpv_signed_userid_t *userid; - - userid = &ARRAY_ELEMENT(primary->signed_userids, u); - return snprintf(s, size, "uid %.*s%s\n", - (int)userid->userid.size, userid->userid.data, - (userid->revoked == COMPROMISED) ? " [COMPROMISED AND REVOKED]" : - (userid->revoked) ? " [REVOKED]" : ""); -} - -/* print a primary key, per RFC 4880 */ -static size_t -fmt_primary(char *s, size_t size, pgpv_primarykey_t *primary) -{ - unsigned i; - size_t cc; - - cc = fmt_pubkey(s, size, &primary->primary, "signature "); - cc += fmt_userid(&s[cc], size - cc, primary, primary->primary_userid); - for (i = 0 ; i < ARRAY_COUNT(primary->signed_userids) ; i++) { - if (i != primary->primary_userid) { - cc += fmt_userid(&s[cc], size - cc, primary, i); - } - } - for (i = 0 ; i < ARRAY_COUNT(primary->signed_subkeys) ; i++) { - cc += fmt_pubkey(&s[cc], size - cc, &ARRAY_ELEMENT(primary->signed_subkeys, i).subkey, "encryption"); - } - cc += snprintf(&s[cc], size - cc, "\n"); - return cc; -} - - -/* check the padding on the signature */ -static int -rsa_padding_check_none(uint8_t *to, int tlen, const uint8_t *from, int flen, int num) -{ - USE_ARG(num); - if (flen > tlen) { - printf("from length larger than to length\n"); - return -1; - } - (void) memset(to, 0x0, tlen - flen); - (void) memcpy(to + tlen - flen, from, flen); - return tlen; -} - -#define RSA_MAX_MODULUS_BITS 16384 -#define RSA_SMALL_MODULUS_BITS 3072 -#define RSA_MAX_PUBEXP_BITS 64 /* exponent limit enforced for "large" modulus only */ - -/* check against the exponent/moudulo operation */ -static int -lowlevel_rsa_public_check(const uint8_t *encbuf, int enclen, uint8_t *dec, const rsa_pubkey_t *rsa) -{ - uint8_t *decbuf; - BIGNUM *decbn; - BIGNUM *encbn; - int decbytes; - int nbytes; - int r; - - nbytes = 0; - r = -1; - decbuf = NULL; - decbn = encbn = NULL; - if (BN_num_bits(rsa->n) > RSA_MAX_MODULUS_BITS) { - printf("rsa r modulus too large\n"); - goto err; - } - if (BN_cmp(rsa->n, rsa->e) <= 0) { - printf("rsa r bad n value\n"); - goto err; - } - if (BN_num_bits(rsa->n) > RSA_SMALL_MODULUS_BITS && - BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) { - printf("rsa r bad exponent limit\n"); - goto err; - } - if ((encbn = BN_new()) == NULL || - (decbn = BN_new()) == NULL || - (decbuf = calloc(1, nbytes = BN_num_bytes(rsa->n))) == NULL) { - printf("allocation failure\n"); - goto err; - } - if (enclen > nbytes) { - printf("rsa r > mod len\n"); - goto err; - } - if (BN_bin2bn(encbuf, enclen, encbn) == NULL) { - printf("null encrypted BN\n"); - goto err; - } - if (BN_cmp(encbn, rsa->n) >= 0) { - printf("rsa r data too large for modulus\n"); - goto err; - } - if (BN_mod_exp(decbn, encbn, rsa->e, rsa->n, NULL) < 0) { - printf("BN_mod_exp < 0\n"); - goto err; - } - decbytes = BN_num_bytes(decbn); - (void) BN_bn2bin(decbn, decbuf); - if ((r = rsa_padding_check_none(dec, nbytes, decbuf, decbytes, 0)) < 0) { - printf("rsa r padding check failed\n"); - } -err: - BN_free(encbn); - BN_free(decbn); - if (decbuf != NULL) { - (void) memset(decbuf, 0x0, nbytes); - free(decbuf); - } - return r; -} - -/* verify */ -static int -rsa_public_decrypt(int enclen, const unsigned char *enc, unsigned char *dec, RSA *rsa, int padding) -{ - rsa_pubkey_t pub; - int ret; - - if (enc == NULL || dec == NULL || rsa == NULL) { - return 0; - } - USE_ARG(padding); - (void) memset(&pub, 0x0, sizeof(pub)); - pub.n = BN_dup(rsa->n); - pub.e = BN_dup(rsa->e); - ret = lowlevel_rsa_public_check(enc, enclen, dec, &pub); - BN_free(pub.n); - BN_free(pub.e); - return ret; -} - -#define SUBKEY_LEN(x) (80 + 80) -#define SIG_LEN 80 -#define UID_LEN 80 - -/* return worst case number of bytes needed to format a primary key */ -static size_t -estimate_primarykey_size(pgpv_primarykey_t *primary) -{ - size_t cc; - - cc = SUBKEY_LEN("signature") + - (ARRAY_COUNT(primary->signed_userids) * UID_LEN) + - (ARRAY_COUNT(primary->signed_subkeys) * SUBKEY_LEN("encrypt uids")); - return cc; -} - -/* use public decrypt to verify a signature */ -static int -pgpv_rsa_public_decrypt(uint8_t *out, const uint8_t *in, size_t length, const pgpv_pubkey_t *pubkey) -{ - RSA *orsa; - int n; - - if ((orsa = calloc(1, sizeof(*orsa))) == NULL) { - return 0; - } - orsa->n = pubkey->bn[RSA_N].bn; - orsa->e = pubkey->bn[RSA_E].bn; - n = rsa_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING); - orsa->n = orsa->e = NULL; - free(orsa); - return n; -} - -/* verify rsa signature */ -static int -rsa_verify(uint8_t *calculated, unsigned calclen, uint8_t hashalg, pgpv_bignum_t *bn, pgpv_pubkey_t *pubkey) -{ - unsigned prefixlen; - unsigned decryptc; - unsigned i; - uint8_t decrypted[8192]; - uint8_t sigbn[8192]; - uint8_t prefix[64]; - size_t keysize; - - keysize = BITS_TO_BYTES(pubkey->bn[RSA_N].bits); - BN_bn2bin(bn[RSA_SIG].bn, sigbn); - decryptc = pgpv_rsa_public_decrypt(decrypted, sigbn, BITS_TO_BYTES(bn[RSA_SIG].bits), pubkey); - if (decryptc != keysize || (decrypted[0] != 0 || decrypted[1] != 1)) { - return 0; - } - if ((prefixlen = digest_get_prefix((unsigned)hashalg, prefix, sizeof(prefix))) == 0) { - printf("rsa_verify: unknown hash algorithm: %d\n", hashalg); - return 0; - } - for (i = 2 ; i < keysize - prefixlen - calclen - 1 ; i++) { - if (decrypted[i] != 0xff) { - return 0; - } - } - if (decrypted[i++] != 0x0) { - return 0; - } - if (memcmp(&decrypted[i], prefix, prefixlen) != 0) { - printf("rsa_verify: wrong hash algorithm\n"); - return 0; - } - return memcmp(&decrypted[i + prefixlen], calculated, calclen) == 0; -} - -/* return 1 if bn <= 0 */ -static int -bignum_is_bad(BIGNUM *bn) -{ - return BN_is_zero(bn) || BN_is_negative(bn); -} - -#define BAD_BIGNUM(s, k) \ - (bignum_is_bad((s)->bn) || BN_cmp((s)->bn, (k)->bn) >= 0) - -#ifndef DSA_MAX_MODULUS_BITS -#define DSA_MAX_MODULUS_BITS 10000 -#endif - -/* verify DSA signature */ -static int -verify_dsa_sig(uint8_t *calculated, unsigned calclen, pgpv_bignum_t *sig, pgpv_pubkey_t *pubkey) -{ - unsigned qbits; - uint8_t calcnum[128]; - uint8_t signum[128]; - BIGNUM *M; - BIGNUM *W; - BIGNUM *t1; - int ret; - - if (pubkey[DSA_P].bn == NULL || pubkey[DSA_Q].bn == NULL || pubkey[DSA_G].bn == NULL) { - return 0; - } - M = W = t1 = NULL; - qbits = pubkey->bn[DSA_Q].bits; - switch(qbits) { - case 160: - case 224: - case 256: - break; - default: - printf("dsa: bad # of Q bits\n"); - return 0; - } - if (pubkey->bn[DSA_P].bits > DSA_MAX_MODULUS_BITS) { - printf("dsa: p too large\n"); - return 0; - } - if (calclen > SHA256_DIGEST_LENGTH) { - printf("dsa: digest too long\n"); - return 0; - } - ret = 0; - if ((M = BN_new()) == NULL || (W = BN_new()) == NULL || (t1 = BN_new()) == NULL || - BAD_BIGNUM(&sig[DSA_R], &pubkey->bn[DSA_Q]) || - BAD_BIGNUM(&sig[DSA_S], &pubkey->bn[DSA_Q]) || - BN_mod_inverse(W, sig[DSA_S].bn, pubkey->bn[DSA_Q].bn, NULL) == NULL) { - goto done; - } - if (calclen > qbits / 8) { - calclen = qbits / 8; - } - if (BN_bin2bn(calculated, (int)calclen, M) == NULL || - !BN_mod_mul(M, M, W, pubkey->bn[DSA_Q].bn, NULL) || - !BN_mod_mul(W, sig[DSA_R].bn, W, pubkey->bn[DSA_Q].bn, NULL) || - !BN_mod_exp(t1, pubkey->bn[DSA_G].bn, M, pubkey->bn[DSA_P].bn, NULL) || - !BN_mod_exp(W, pubkey->bn[DSA_Y].bn, W, pubkey->bn[DSA_P].bn, NULL) || - !BN_mod_mul(t1, t1, W, pubkey->bn[DSA_P].bn, NULL) || - !BN_div(NULL, t1, t1, pubkey->bn[DSA_Q].bn, NULL)) { - goto done; - } - /* only compare the first q bits */ - BN_bn2bin(t1, calcnum); - BN_bn2bin(sig[DSA_R].bn, signum); - ret = memcmp(calcnum, signum, BITS_TO_BYTES(qbits)) == 0; -done: - if (M) { - BN_free(M); - } - if (W) { - BN_free(W); - } - if (t1) { - BN_free(t1); - } - return ret; -} - -#define TIME_SNPRINTF(_cc, _buf, _size, _fmt, _val) do { \ - time_t _t; \ - char *_s; \ - \ - _t = _val; \ - _s = ctime(&_t); \ - _cc += snprintf(_buf, _size, _fmt, _s); \ -} while(/*CONSTCOND*/0) - -/* check dates on signature and key are valid */ -static size_t -valid_dates(pgpv_signature_t *signature, pgpv_pubkey_t *pubkey, char *buf, size_t size) -{ - time_t now; - time_t t; - size_t cc; - - cc = 0; - if (signature->birth < pubkey->birth) { - TIME_SNPRINTF(cc, buf, size, "Signature time (%.24s) was before pubkey creation ", signature->birth); - TIME_SNPRINTF(cc, &buf[cc], size - cc, "(%s)\n", pubkey->birth); - return cc; - } - now = time(NULL); - if (signature->expiry != 0) { - if ((t = signature->birth + signature->expiry) < now) { - TIME_SNPRINTF(cc, buf, size, "Signature expired on %.24s\n", t); - return cc; - } - } - if (now < signature->birth) { - TIME_SNPRINTF(cc, buf, size, "Signature not valid before %.24s\n", signature->birth); - return cc; - } - return 0; -} - -/* check if the signing key has expired */ -static int -key_expired(pgpv_pubkey_t *pubkey, char *buf, size_t size) -{ - time_t now; - time_t t; - size_t cc; - - now = time(NULL); - cc = 0; - if (pubkey->expiry != 0) { - if ((t = pubkey->birth + pubkey->expiry) < now) { - TIME_SNPRINTF(cc, buf, size, "Pubkey expired on %.24s\n", t); - return (int)cc; - } - } - if (now < pubkey->birth) { - TIME_SNPRINTF(cc, buf, size, "Pubkey not valid before %.24s\n", pubkey->birth); - return (int)cc; - } - return 0; -} - -/* find the leading onepass packet */ -static size_t -find_onepass(pgpv_cursor_t *cursor, size_t datastart) -{ - size_t pkt; - - for (pkt = datastart ; pkt < ARRAY_COUNT(cursor->pgp->pkts) ; pkt++) { - if (ARRAY_ELEMENT(cursor->pgp->pkts, pkt).tag == ONEPASS_SIGNATURE_PKT) { - return pkt + 1; - } - } - snprintf(cursor->why, sizeof(cursor->why), "No signature to verify"); - return 0; -} - -static const char *armor_begins[] = { - "-----BEGIN PGP SIGNED MESSAGE-----\n", - "-----BEGIN PGP MESSAGE-----\n", - NULL -}; - -/* return non-zero if the buf introduces an armored message */ -static int -is_armored(const char *buf, size_t size) -{ - const char **arm; - const char *nl; - size_t n; - - if ((nl = memchr(buf, '\n', size)) == NULL) { - return 0; - } - n = (size_t)(nl - buf); - for (arm = armor_begins ; *arm ; arm++) { - if (strncmp(buf, *arm, n) == 0) { - return 1; - } - } - return 0; -} - -#define SIGSTART "-----BEGIN PGP SIGNATURE-----\n" -#define SIGEND "-----END PGP SIGNATURE-----\n" - -/* for ascii armor, we don't get a onepass packet - make one */ -static const char *cons_onepass = "\304\015\003\0\0\0\0\377\377\377\377\377\377\377\377\1"; - -/* read ascii armor */ -static int -read_ascii_armor(pgpv_cursor_t *cursor, pgpv_mem_t *mem, const char *filename) -{ - pgpv_onepass_t *onepass; - pgpv_sigpkt_t *sigpkt; - pgpv_pkt_t litdata; - uint8_t binsig[8192]; - uint8_t *datastart; - uint8_t *sigend; - uint8_t *p; - size_t binsigsize; - - /* cons up litdata pkt */ - memset(&litdata, 0x0, sizeof(litdata)); - litdata.u.litdata.mem = ARRAY_COUNT(cursor->pgp->areas) - 1; - p = mem->mem; - /* jump over signed message line */ - if ((p = memmem(mem->mem, mem->size, "\n\n", 2)) == NULL) { - snprintf(cursor->why, sizeof(cursor->why), "malformed armor at offset 0"); - return 0; - } - p += 2; - litdata.tag = LITDATA_PKT; - litdata.s.data = p; - litdata.u.litdata.offset = (size_t)(p - mem->mem); - litdata.u.litdata.filename = (uint8_t *)strdup(filename); - if ((p = memmem(datastart = p, mem->size - litdata.offset, SIGSTART, strlen(SIGSTART))) == NULL) { - snprintf(cursor->why, sizeof(cursor->why), - "malformed armor - no sig - at %zu", (size_t)(p - mem->mem)); - return 0; - } - litdata.u.litdata.len = litdata.s.size = (size_t)(p - datastart); - p += strlen(SIGSTART); - if ((p = memmem(p, mem->size, "\n\n", 2)) == NULL) { - snprintf(cursor->why, sizeof(cursor->why), - "malformed armed signature at %zu", (size_t)(p - mem->mem)); - return 0; - } - p += 2; - sigend = memmem(p, mem->size, SIGEND, strlen(SIGEND)); - binsigsize = b64decode((char *)p, (size_t)(sigend - p), binsig, sizeof(binsig)); - - read_binary_memory(cursor->pgp, "signature", cons_onepass, 15); - ARRAY_APPEND(cursor->pgp->pkts, litdata); - read_binary_memory(cursor->pgp, "signature", binsig, binsigsize - 3); - /* XXX - hardwired - 3 is format and length */ - - /* fix up packets in the packet array now we have them there */ - onepass = &ARRAY_ELEMENT(cursor->pgp->pkts, ARRAY_COUNT(cursor->pgp->pkts) - 1 - 2).u.onepass; - sigpkt = &ARRAY_LAST(cursor->pgp->pkts).u.sigpkt; - memcpy(onepass->keyid, sigpkt->sig.signer, sizeof(onepass->keyid)); - onepass->hashalg = sigpkt->sig.hashalg; - onepass->keyalg = sigpkt->sig.keyalg; - return 1; -} - -/* read ascii armor from a file */ -static int -read_ascii_armor_file(pgpv_cursor_t *cursor, const char *filename) -{ - /* cons up litdata pkt */ - read_file(cursor->pgp, filename); - return read_ascii_armor(cursor, &ARRAY_LAST(cursor->pgp->areas), filename); -} - -/* read ascii armor from memory */ -static int -read_ascii_armor_memory(pgpv_cursor_t *cursor, const void *p, size_t size) -{ - pgpv_mem_t *mem; - - /* cons up litdata pkt */ - ARRAY_EXPAND(cursor->pgp->areas); - ARRAY_COUNT(cursor->pgp->areas) += 1; - mem = &ARRAY_LAST(cursor->pgp->areas); - memset(mem, 0x0, sizeof(*mem)); - mem->size = size; - mem->mem = __UNCONST(p); - mem->dealloc = 0; - return read_ascii_armor(cursor, mem, "[stdin]"); -} - -/* set up the data to verify */ -static int -setup_data(pgpv_cursor_t *cursor, pgpv_t *pgp, const void *p, ssize_t size) -{ - FILE *fp; - char buf[BUFSIZ]; - - if (cursor == NULL || pgp == NULL || p == NULL) { - return 0; - } - memset(cursor, 0x0, sizeof(*cursor)); - ARRAY_APPEND(pgp->datastarts, pgp->pkt); - cursor->pgp = pgp; - if (size < 0) { - /* we have a file name in p */ - if ((fp = fopen(p, "r")) == NULL) { - snprintf(cursor->why, sizeof(cursor->why), "No such file '%s'", (const char *)p); - return 0; - } - if (fgets(buf, (int)sizeof(buf), fp) == NULL) { - fclose(fp); - snprintf(cursor->why, sizeof(cursor->why), "can't read file '%s'", (const char *)p); - return 0; - } - if (is_armored(buf, sizeof(buf))) { - read_ascii_armor_file(cursor, p); - } else { - read_binary_file(pgp, "signature", "%s", p); - } - fclose(fp); - } else { - if (is_armored(p, (size_t)size)) { - read_ascii_armor_memory(cursor, p, (size_t)size); - } else { - read_binary_memory(pgp, "signature", p, (size_t)size); - } - } - return 1; -} - -/* get the data and size from litdata packet */ -static uint8_t * -get_literal_data(pgpv_cursor_t *cursor, pgpv_litdata_t *litdata, size_t *size) -{ - pgpv_mem_t *mem; - - if (litdata->s.data == NULL && litdata->s.size == 0) { - mem = &ARRAY_ELEMENT(cursor->pgp->areas, litdata->mem); - *size = litdata->len; - return &mem->mem[litdata->offset]; - } - *size = litdata->s.size; - return litdata->s.data; -} - -/* -RFC 4880 describes the structure of v4 keys as: - - Primary-Key - [Revocation Self Signature] - [Direct Key Signature...] - User ID [Signature ...] - [User ID [Signature ...] ...] - [User Attribute [Signature ...] ...] - [[Subkey [Binding-Signature-Revocation] - Primary-Key-Binding-Signature] ...] - -and that's implemented below as a recursive descent parser. -It has had to be modified, though: see the comment - - some keys out there have user ids where they shouldn't - -to look like: - - Primary-Key - [Revocation Self Signature] - [Direct Key Signature...] - [User ID [Signature ...] - [User ID [Signature ...] ...] - [User Attribute [Signature ...] ...] - [Subkey [Binding-Signature-Revocation] - Primary-Key-Binding-Signature] ...] - -to accommodate keyrings set up by gpg -*/ - -/* recognise a primary key */ -static int -recog_primary_key(pgpv_t *pgp, pgpv_primarykey_t *primary) -{ - pgpv_signed_userattr_t userattr; - pgpv_signed_userid_t userid; - pgpv_signed_subkey_t subkey; - pgpv_signature_t signature; - pgpv_pkt_t *pkt; - - pkt = &ARRAY_ELEMENT(pgp->pkts, pgp->pkt); - memset(primary, 0x0, sizeof(*primary)); - read_pubkey(&primary->primary, pkt->s.data, pkt->s.size, 0); - pgp->pkt += 1; - if (pkt_sigtype_is(pgp, SIGTYPE_KEY_REVOCATION)) { - if (!recog_signature(pgp, &primary->revoc_self_sig)) { - printf("recog_primary_key: no signature/trust at PGPV_SIGTYPE_KEY_REVOCATION\n"); - return 0; - } - } - while (pkt_sigtype_is(pgp, SIGTYPE_DIRECT_KEY)) { - if (!recog_signature(pgp, &signature)) { - printf("recog_primary_key: no signature/trust at PGPV_SIGTYPE_DIRECT_KEY\n"); - return 0; - } - if (signature.keyexpiry) { - /* XXX - check it's a good key expiry */ - primary->primary.expiry = signature.keyexpiry; - } - ARRAY_APPEND(primary->direct_sigs, signature); - } - /* some keys out there have user ids where they shouldn't */ - do { - if (!recog_userid(pgp, &userid)) { - printf("recog_primary_key: not userid\n"); - return 0; - } - ARRAY_APPEND(primary->signed_userids, userid); - if (userid.primary_userid) { - primary->primary_userid = ARRAY_COUNT(primary->signed_userids) - 1; - } - while (pkt_is(pgp, USERID_PKT)) { - if (!recog_userid(pgp, &userid)) { - printf("recog_primary_key: not signed secondary userid\n"); - return 0; - } - ARRAY_APPEND(primary->signed_userids, userid); - if (userid.primary_userid) { - primary->primary_userid = ARRAY_COUNT(primary->signed_userids) - 1; - } - } - while (pkt_is(pgp, USER_ATTRIBUTE_PKT)) { - if (!recog_userattr(pgp, &userattr)) { - printf("recog_primary_key: not signed user attribute\n"); - return 0; - } - ARRAY_APPEND(primary->signed_userattrs, userattr); - } - while (pkt_is(pgp, PUB_SUBKEY_PKT)) { - if (!recog_subkey(pgp, &subkey)) { - printf("recog_primary_key: not signed public subkey\n"); - return 0; - } - pgpv_calc_keyid(&subkey.subkey); - ARRAY_APPEND(primary->signed_subkeys, subkey); - } - } while (pgp->pkt < ARRAY_COUNT(pgp->pkts) && pkt_is(pgp, USERID_PKT)); - primary->fmtsize = estimate_primarykey_size(primary); - return 1; -} - -/* parse all of the packets for a given operation */ -static int -read_all_packets(pgpv_t *pgp, pgpv_mem_t *mem, const char *op) -{ - pgpv_primarykey_t primary; - - if (op == NULL) { - return 0; - } - if (strcmp(pgp->op = op, "pubring") == 0) { - mem->allowed = PUBRING_ALLOWED; - /* pubrings have thousands of small packets */ - ARRAY_EXPAND_SIZED(pgp->pkts, 0, 5000); - } else if (strcmp(op, "signature") == 0) { - mem->allowed = SIGNATURE_ALLOWED; - } else { - mem->allowed = ""; - } - for (mem->cc = 0; mem->cc < mem->size ; ) { - if (!read_pkt(pgp, mem)) { - return 0; - } - } - if (strcmp(op, "pubring") == 0) { - for (pgp->pkt = 0; pgp->pkt < ARRAY_COUNT(pgp->pkts) && recog_primary_key(pgp, &primary) ; ) { - pgpv_calc_keyid(&primary.primary); - ARRAY_APPEND(pgp->primaries, primary); - } - if (pgp->pkt < ARRAY_COUNT(pgp->pkts)) { - printf("short pubring recognition???\n"); - } - } - pgp->pkt = ARRAY_COUNT(pgp->pkts); - return 1; -} - -/* create a filename, read it, and then parse according to "op" */ -static int -read_binary_file(pgpv_t *pgp, const char *op, const char *fmt, ...) -{ - va_list args; - char buf[1024]; - - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - if (!read_file(pgp, buf)) { - return 0; - } - return read_all_packets(pgp, &ARRAY_LAST(pgp->areas), op); -} - -/* parse memory according to "op" */ -static int -read_binary_memory(pgpv_t *pgp, const char *op, const void *memory, size_t size) -{ - pgpv_mem_t *mem; - - ARRAY_EXPAND(pgp->areas); - ARRAY_COUNT(pgp->areas) += 1; - mem = &ARRAY_LAST(pgp->areas); - memset(mem, 0x0, sizeof(*mem)); - mem->size = size; - mem->mem = __UNCONST(memory); - mem->dealloc = 0; - return read_all_packets(pgp, mem, op); -} - -/* fixup the detached signature packets */ -static int -fixup_detached(pgpv_cursor_t *cursor, const char *f) -{ - pgpv_onepass_t *onepass; - const char *dot; - pgpv_pkt_t sigpkt; - pgpv_pkt_t litdata; - pgpv_mem_t *mem; - size_t el; - char original[MAXPATHLEN]; - - /* cons up litdata pkt */ - if ((dot = strrchr(f, '.')) == NULL || strcasecmp(dot, ".sig") != 0) { - printf("weird filename '%s'\n", f); - return 0; - } - /* hold sigpkt in a temp var while we insert onepass and litdata */ - el = ARRAY_COUNT(cursor->pgp->pkts) - 1; - sigpkt = ARRAY_ELEMENT(cursor->pgp->pkts, el); - ARRAY_DELETE(cursor->pgp->pkts, el); - ARRAY_EXPAND(cursor->pgp->pkts); - /* get onepass packet, append to packets */ - read_binary_memory(cursor->pgp, "signature", cons_onepass, 15); - onepass = &ARRAY_ELEMENT(cursor->pgp->pkts, el).u.onepass; - /* read the original file into litdata */ - snprintf(original, sizeof(original), "%.*s", (int)(dot - f), f); - if (!read_file(cursor->pgp, original)) { - printf("can't read file '%s'\n", original); - return 0; - } - memset(&litdata, 0x0, sizeof(litdata)); - mem = &ARRAY_LAST(cursor->pgp->areas); - litdata.tag = LITDATA_PKT; - litdata.s.data = mem->mem; - litdata.u.litdata.format = LITDATA_BINARY; - litdata.u.litdata.offset = 0; - litdata.u.litdata.filename = (uint8_t *)strdup(original); - litdata.u.litdata.mem = ARRAY_COUNT(cursor->pgp->areas) - 1; - litdata.u.litdata.len = litdata.s.size = mem->size; - ARRAY_APPEND(cursor->pgp->pkts, litdata); - ARRAY_APPEND(cursor->pgp->pkts, sigpkt); - memcpy(onepass->keyid, sigpkt.u.sigpkt.sig.signer, sizeof(onepass->keyid)); - onepass->hashalg = sigpkt.u.sigpkt.sig.hashalg; - onepass->keyalg = sigpkt.u.sigpkt.sig.keyalg; - return 1; -} - -/* match the calculated signature against the oen in the signature packet */ -static int -match_sig(pgpv_cursor_t *cursor, pgpv_signature_t *signature, pgpv_pubkey_t *pubkey, uint8_t *data, size_t size) -{ - unsigned calclen; - uint8_t calculated[64]; - int match; - - calclen = pgpv_digest_memory(calculated, sizeof(calculated), - data, size, - get_ref(&signature->hashstart), signature->hashlen, - (signature->type == SIGTYPE_TEXT) ? 't' : 'b'); - if (ALG_IS_RSA(signature->keyalg)) { - match = rsa_verify(calculated, calclen, signature->hashalg, signature->bn, pubkey); - } else if (ALG_IS_DSA(signature->keyalg)) { - match = verify_dsa_sig(calculated, calclen, signature->bn, pubkey); - } else { - snprintf(cursor->why, sizeof(cursor->why), "Signature type %u not recognised", signature->keyalg); - return 0; - } - if (!match && signature->type == SIGTYPE_TEXT) { - /* second try for cleartext data, ignoring trailing whitespace */ - calclen = pgpv_digest_memory(calculated, sizeof(calculated), - data, size, - get_ref(&signature->hashstart), signature->hashlen, 'w'); - if (ALG_IS_RSA(signature->keyalg)) { - match = rsa_verify(calculated, calclen, signature->hashalg, signature->bn, pubkey); - } else if (ALG_IS_DSA(signature->keyalg)) { - match = verify_dsa_sig(calculated, calclen, signature->bn, pubkey); - } - } - if (!match) { - snprintf(cursor->why, sizeof(cursor->why), "Signature on data did not match"); - return 0; - } - if (valid_dates(signature, pubkey, cursor->why, sizeof(cursor->why)) > 0) { - return 0; - } - if (key_expired(pubkey, cursor->why, sizeof(cursor->why))) { - return 0; - } - if (signature->revoked) { - snprintf(cursor->why, sizeof(cursor->why), "Signature was revoked"); - return 0; - } - return 1; -} - -/* check return value from getenv */ -static const char * -nonnull_getenv(const char *key) -{ - char *value; - - return ((value = getenv(key)) == NULL) ? "" : value; -} - -/************************************************************************/ -/* start of exported functions */ -/************************************************************************/ - -/* close all stuff */ -int -pgpv_close(pgpv_t *pgp) -{ - unsigned i; - - if (pgp == NULL) { - return 0; - } - for (i = 0 ; i < ARRAY_COUNT(pgp->areas) ; i++) { - if (ARRAY_ELEMENT(pgp->areas, i).size > 0) { - closemem(&ARRAY_ELEMENT(pgp->areas, i)); - } - } - return 1; -} - -/* return the formatted entry for the primary key desired */ -size_t -pgpv_get_entry(pgpv_t *pgp, unsigned ent, char **ret) -{ - size_t cc; - - if (ret == NULL || pgp == NULL || ent >= ARRAY_COUNT(pgp->primaries)) { - return 0; - } - *ret = NULL; - cc = ARRAY_ELEMENT(pgp->primaries, ent).fmtsize; - if ((*ret = calloc(1, cc)) == NULL) { - return 0; - } - return fmt_primary(*ret, cc, &ARRAY_ELEMENT(pgp->primaries, ent)); -} - -/* find key id */ -int -pgpv_find_keyid(pgpv_t *pgp, const char *strkeyid, uint8_t *keyid) -{ - unsigned i; - uint8_t binkeyid[PGPV_KEYID_LEN]; - size_t off; - size_t cmp; - - if (strkeyid == NULL && keyid == NULL) { - return 0; - } - if (strkeyid) { - str_to_keyid(strkeyid, binkeyid); - cmp = strlen(strkeyid) / 2; - } else { - memcpy(binkeyid, keyid, sizeof(binkeyid)); - cmp = PGPV_KEYID_LEN; - } - off = PGPV_KEYID_LEN - cmp; - for (i = 0 ; i < ARRAY_COUNT(pgp->primaries) ; i++) { - if (memcmp(&ARRAY_ELEMENT(pgp->primaries, i).primary.keyid[off], &binkeyid[off], cmp) == 0) { - return i; - } - } - return -1; -} - -/* verify the signed packets we have */ -size_t -pgpv_verify(pgpv_cursor_t *cursor, pgpv_t *pgp, const void *p, ssize_t size) -{ - pgpv_signature_t *signature; - pgpv_onepass_t *onepass; - pgpv_litdata_t *litdata; - pgpv_pubkey_t *pubkey; - unsigned primary; - uint8_t *data; - size_t pkt; - size_t insize; - char strkeyid[PGPV_STR_KEYID_LEN]; - int j; - - if (cursor == NULL || pgp == NULL || p == NULL) { - return 0; - } - if (!setup_data(cursor, pgp, p, size)) { - snprintf(cursor->why, sizeof(cursor->why), "No input data"); - return 0; - } - if (ARRAY_COUNT(cursor->pgp->pkts) == ARRAY_LAST(cursor->pgp->datastarts) + 1) { - /* got detached signature here */ - if (!fixup_detached(cursor, p)) { - snprintf(cursor->why, sizeof(cursor->why), "Can't read signed file '%s'", (const char *)p); - return 0; - } - } - if ((pkt = find_onepass(cursor, ARRAY_LAST(cursor->pgp->datastarts))) == 0) { - snprintf(cursor->why, sizeof(cursor->why), "No signature found"); - return 0; - } - pkt -= 1; - onepass = &ARRAY_ELEMENT(cursor->pgp->pkts, pkt).u.onepass; - litdata = &ARRAY_ELEMENT(cursor->pgp->pkts, pkt + 1).u.litdata; - signature = &ARRAY_ELEMENT(cursor->pgp->pkts, pkt + 2).u.sigpkt.sig; - /* sanity check values in signature and onepass agree */ - if (signature->birth == 0) { - fmt_time(cursor->why, sizeof(cursor->why), "Signature creation time [", - signature->birth, "] out of range", 0); - return 0; - } - if (memcmp(onepass->keyid, signature->signer, PGPV_KEYID_LEN) != 0) { - fmt_binary(strkeyid, sizeof(strkeyid), onepass->keyid, (unsigned)sizeof(onepass->keyid)); - snprintf(cursor->why, sizeof(cursor->why), "Signature key id %s does not match onepass keyid", - strkeyid); - return 0; - } - if (onepass->hashalg != signature->hashalg) { - snprintf(cursor->why, sizeof(cursor->why), "Signature hashalg %u does not match onepass hashalg %u", - signature->hashalg, onepass->hashalg); - return 0; - } - if (onepass->keyalg != signature->keyalg) { - snprintf(cursor->why, sizeof(cursor->why), "Signature keyalg %u does not match onepass keyalg %u", - signature->keyalg, onepass->keyalg); - return 0; - } - if ((j = pgpv_find_keyid(cursor->pgp, NULL, onepass->keyid)) < 0) { - fmt_binary(strkeyid, sizeof(strkeyid), onepass->keyid, (unsigned)sizeof(onepass->keyid)); - snprintf(cursor->why, sizeof(cursor->why), "Signature key id %s not found ", strkeyid); - return 0; - } - primary = (unsigned)j; - pubkey = &ARRAY_ELEMENT(cursor->pgp->primaries, primary).primary; - cursor->sigtime = signature->birth; - /* calc hash on data packet */ - data = get_literal_data(cursor, litdata, &insize); - if (!match_sig(cursor, signature, pubkey, data, insize)) { - return 0; - } - ARRAY_APPEND(cursor->datacookies, pkt); - ARRAY_APPEND(cursor->found, primary); - return pkt + 1; -} - -/* set up the pubkey keyring */ -int -pgpv_read_pubring(pgpv_t *pgp, const void *keyring, ssize_t size) -{ - if (pgp == NULL) { - return 0; - } - if (keyring) { - return (size > 0) ? - read_binary_memory(pgp, "pubring", keyring, (size_t)size) : - read_binary_file(pgp, "pubring", "%s", keyring); - } - return read_binary_file(pgp, "pubring", "%s/%s", nonnull_getenv("HOME"), ".gnupg/pubring.gpg"); -} - -/* get verified data as a string, return its size */ -size_t -pgpv_get_verified(pgpv_cursor_t *cursor, size_t cookie, char **ret) -{ - pgpv_litdata_t *litdata; - uint8_t *data; - size_t size; - size_t pkt; - - if (ret == NULL || cursor == NULL || cookie == 0) { - return 0; - } - *ret = NULL; - if ((pkt = find_onepass(cursor, cookie - 1)) == 0) { - return 0; - } - litdata = &ARRAY_ELEMENT(cursor->pgp->pkts, pkt).u.litdata; - data = get_literal_data(cursor, litdata, &size); - if ((*ret = calloc(1, size)) == NULL) { - return 0; - } - memcpy(*ret, data, size); - return size; -} diff --git a/security/libnetpgpverify/files/src/libverify/pgpsum.c b/security/libnetpgpverify/files/src/libverify/pgpsum.c deleted file mode 100644 index 3516e053b0b..00000000000 --- a/security/libnetpgpverify/files/src/libverify/pgpsum.c +++ /dev/null @@ -1,192 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> - -#include <err.h> -#include <inttypes.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "digest.h" -#include "pgpsum.h" - -#ifndef USE_ARG -#define USE_ARG(x) /*LINTED*/(void)&(x) -#endif - -/* add the ascii armor line endings (except for last line) */ -static size_t -don_armor(digest_t *hash, uint8_t *in, size_t insize, int doarmor) -{ - uint8_t *from; - uint8_t *newp; - uint8_t *p; - uint8_t dos_line_end[2]; - - dos_line_end[0] = '\r'; - dos_line_end[1] = '\n'; - for (from = in ; (p = memchr(from, '\n', insize - (size_t)(from - in))) != NULL ; from = p + 1) { - for (newp = p ; doarmor == 'w' && newp > from ; --newp) { - if (*(newp - 1) != ' ' && *(newp - 1) != '\t') { - break; - } - } - digest_update(hash, from, (size_t)(newp - from)); - digest_update(hash, dos_line_end, sizeof(dos_line_end)); - } - digest_update(hash, from, insize - (size_t)(from - in)); - return 1; -} - -#ifdef NETPGPV_DEBUG -/* just for giggles, write what we're about to checksum */ -static int -writefile(uint8_t *mem, size_t insize) -{ - size_t cc; - size_t wc; - char template[256]; - int fd; - - snprintf(template, sizeof(template), "netpgpvmd.XXXXXX"); - if ((fd = mkstemp(template)) < 0) { - fprintf(stderr, "can't mkstemp %s\n", template); - return 0; - } - for (cc = 0 ; cc < insize ; cc += wc) { - if ((wc = write(fd, &mem[cc], insize - cc)) <= 0) { - fprintf(stderr, "short write\n"); - break; - } - } - close(fd); - return 1; -} -#endif - -/* return non-zero if this is actually an armored piece already */ -static int -already_armored(uint8_t *in, size_t insize) -{ - uint8_t *from; - uint8_t *p; - - for (from = in ; (p = memchr(from, '\n', insize - (size_t)(from - in))) != NULL ; from = p + 1) { - if (*(p - 1) != '\r') { - return 0; - } - } - return 1; -} - -/* calculate the checksum for the data we have */ -static int -calcsum(uint8_t *out, size_t size, uint8_t *mem, size_t cc, const uint8_t *hashed, size_t hashsize, int doarmor) -{ - digest_t hash; - uint32_t len32; - uint16_t len16; - uint8_t hashalg; - uint8_t trailer[6]; - - USE_ARG(size); - /* hashed data is non-null (previously checked) */ - hashalg = hashed[3]; - memcpy(&len16, &hashed[4], sizeof(len16)); - len32 = ntohs(len16) + 6; - len32 = htonl(len32); - trailer[0] = 0x04; - trailer[1] = 0xff; - memcpy(&trailer[2], &len32, sizeof(len32)); -#ifdef NETPGPV_DEBUG - writefile(mem, cc); -#endif - digest_init(&hash, (const unsigned)hashalg); - if (strchr("tw", doarmor) != NULL && !already_armored(mem, cc)) { - /* this took me ages to find - something causes gpg to truncate its input */ - don_armor(&hash, mem, cc - 1, doarmor); - } else { - digest_update(&hash, mem, cc); - } - if (hashed) { - digest_update(&hash, hashed, hashsize); - } - digest_update(&hash, trailer, sizeof(trailer)); - return digest_final(out, &hash); -} - -/* open the file, mmap it, and then get the checksum on that */ -int -pgpv_digest_file(uint8_t *data, size_t size, const char *name, const uint8_t *hashed, size_t hashsize, int doarmor) -{ - struct stat st; - uint8_t *mem; - size_t cc; - FILE *fp; - int ret; - - if (hashed == NULL || data == NULL || name == NULL) { - fprintf(stderr, "no hashed data provided\n"); - return 0; - } - ret = 0; - mem = NULL; - cc = 0; - if ((fp = fopen(name, "r")) == NULL) { - warn("%s - not found", name); - return 0; - } - if (fstat(fileno(fp), &st) < 0) { - warn("%s - can't stat", name); - goto done; - } - cc = (size_t)(st.st_size); - if ((mem = mmap(NULL, cc, PROT_READ, MAP_SHARED, fileno(fp), 0)) == MAP_FAILED) { - warn("%s - can't mmap", name); - goto done; - } - ret = calcsum(data, size, mem, cc, hashed, hashsize, doarmor); -done: - if (data) { - munmap(mem, cc); - } - fclose(fp); - return ret; -} - -/* calculate the digest over memory too */ -int -pgpv_digest_memory(uint8_t *data, size_t size, void *mem, size_t cc, const uint8_t *hashed, size_t hashsize, int doarmor) -{ - if (hashed == NULL || data == NULL || mem == NULL) { - fprintf(stderr, "no hashed data provided\n"); - return 0; - } - return calcsum(data, size, mem, cc, hashed, hashsize, doarmor); -} diff --git a/security/libnetpgpverify/files/src/libverify/pgpsum.h b/security/libnetpgpverify/files/src/libverify/pgpsum.h deleted file mode 100644 index 75eb2276248..00000000000 --- a/security/libnetpgpverify/files/src/libverify/pgpsum.h +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef PGPSUM_H_ -#define PGPSUM_H_ 20121003 - -#include <sys/types.h> - -#include <inttypes.h> - -int pgpv_digest_file(uint8_t */*buf*/, size_t /*size*/, const char */*name*/, const uint8_t */*hashed*/, size_t /*hashsize*/, int /*doarmor*/); -int pgpv_digest_memory(uint8_t */*buf*/, size_t /*size*/, void */*memory*/, size_t /*cc*/, const uint8_t */*hashed*/, size_t /*hashsize*/, int /*doarmor*/); - -#endif diff --git a/security/libnetpgpverify/files/src/libverify/verify.h b/security/libnetpgpverify/files/src/libverify/verify.h deleted file mode 100644 index 9e545abad43..00000000000 --- a/security/libnetpgpverify/files/src/libverify/verify.h +++ /dev/null @@ -1,292 +0,0 @@ -/*- - * Copyright (c) 2012,2013 Alistair Crooks <agc@NetBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef NETPGP_VERIFY_H_ -#define NETPGP_VERIFY_H_ 20131219 - -#include <sys/types.h> - -#include <inttypes.h> - -#ifndef PGPV_ARRAY -/* creates 2 unsigned vars called "name"c and "name"size in current scope */ -/* also creates an array called "name"s in current scope */ -#define PGPV_ARRAY(type, name) \ - unsigned name##c; unsigned name##vsize; type *name##s -#endif - -/* 64bit key ids */ -#define PGPV_KEYID_LEN 8 -#define PGPV_STR_KEYID_LEN (PGPV_KEYID_LEN + PGPV_KEYID_LEN + 1) - -/* bignum structure */ -typedef struct pgpv_bignum_t { - void *bn; /* hide the implementation details */ - uint16_t bits; /* cached number of bits */ -} pgpv_bignum_t; - -/* right now, our max binary digest length is 20 bytes */ -#define PGPV_MAX_HASH_LEN 20 - -/* fingerprint */ -typedef struct pgpv_fingerprint_t { - uint8_t hashalg; /* algorithm for digest */ - uint8_t v[PGPV_MAX_HASH_LEN]; /* the digest */ - uint32_t len; /* its length */ -} pgpv_fingerprint_t; - -/* specify size for array of bignums */ -#define PGPV_MAX_PUBKEY_BN 4 - -/* public key */ -typedef struct pgpv_pubkey_t { - pgpv_fingerprint_t fingerprint; /* key fingerprint i.e. digest */ - uint8_t keyid[PGPV_KEYID_LEN]; /* last 8 bytes of v4 keys */ - int64_t birth; /* creation time */ - int64_t expiry; /* expiry time */ - pgpv_bignum_t bn[PGPV_MAX_PUBKEY_BN]; /* bignums */ - uint8_t keyalg; /* key algorithm */ - uint8_t hashalg; /* hash algorithm */ - uint8_t version; /* key version */ -} pgpv_pubkey_t; - -#define PGPV_MAX_SESSKEY_BN 2 - -/* a (size, byte array) string */ -typedef struct pgpv_string_t { - size_t size; - uint8_t *data; -} pgpv_string_t; - -typedef struct pgpv_ref_t { - void *vp; - size_t offset; - unsigned mem; -} pgpv_ref_t; - -#define PGPV_MAX_SECKEY_BN 4 - -typedef struct pgpv_compress_t { - pgpv_string_t s; - uint8_t compalg; -} pgpv_compress_t; - -/* a packet dealing with trust */ -typedef struct pgpv_trust_t { - uint8_t level; - uint8_t amount; -} pgpv_trust_t; - -/* a signature sub packet */ -typedef struct pgpv_sigsubpkt_t { - pgpv_string_t s; - uint8_t tag; - uint8_t critical; -} pgpv_sigsubpkt_t; - -#define PGPV_MAX_SIG_BN 2 - -typedef struct pgpv_signature_t { - uint8_t *signer; /* key id of signer */ - pgpv_ref_t hashstart; - uint8_t *hash2; - uint8_t *mpi; - int64_t birth; - int64_t keyexpiry; - int64_t expiry; - uint32_t hashlen; - uint8_t version; - uint8_t type; - uint8_t keyalg; - uint8_t hashalg; - uint8_t trustlevel; - uint8_t trustamount; - pgpv_bignum_t bn[PGPV_MAX_SIG_BN]; - char *regexp; - char *pref_key_server; - char *policy; - char *features; - char *why_revoked; - uint8_t *revoke_fingerprint; - uint8_t revoke_alg; - uint8_t revoke_sensitive; - uint8_t trustsig; - uint8_t revocable; - uint8_t pref_symm_alg; - uint8_t pref_hash_alg; - uint8_t pref_compress_alg; - uint8_t key_server_modify; - uint8_t notation; - uint8_t type_key; - uint8_t primary_userid; - uint8_t revoked; /* subtract 1 to get real reason, 0 == not revoked */ -} pgpv_signature_t; - -/* a signature packet */ -typedef struct pgpv_sigpkt_t { - pgpv_signature_t sig; - uint16_t subslen; - uint16_t unhashlen; - PGPV_ARRAY(pgpv_sigsubpkt_t, subpkts); -} pgpv_sigpkt_t; - -/* a one-pass signature packet */ -typedef struct pgpv_onepass_t { - uint8_t keyid[PGPV_KEYID_LEN]; - uint8_t version; - uint8_t type; - uint8_t hashalg; - uint8_t keyalg; - uint8_t nested; -} pgpv_onepass_t; - -/* a literal data packet */ -typedef struct pgpv_litdata_t { - uint8_t *filename; - pgpv_string_t s; - uint32_t secs; - uint8_t namelen; - char format; - unsigned mem; - size_t offset; - size_t len; -} pgpv_litdata_t; - -/* user attributes - images */ -typedef struct pgpv_userattr_t { - size_t len; - PGPV_ARRAY(pgpv_string_t, subattrs); -} pgpv_userattr_t; - -/* a general PGP packet */ -typedef struct pgpv_pkt_t { - uint8_t tag; - uint8_t newfmt; - uint8_t allocated; - uint8_t mement; - size_t offset; - pgpv_string_t s; - union { - pgpv_sigpkt_t sigpkt; - pgpv_onepass_t onepass; - pgpv_litdata_t litdata; - pgpv_compress_t compressed; - pgpv_trust_t trust; - pgpv_pubkey_t pubkey; - pgpv_string_t userid; - pgpv_userattr_t userattr; - } u; -} pgpv_pkt_t; - -/* a memory structure */ -typedef struct pgpv_mem_t { - size_t size; - size_t cc; - uint8_t *mem; - FILE *fp; - uint8_t dealloc; - const char *allowed; /* the types of packet that are allowed */ -} pgpv_mem_t; - -/* packet parser */ - -typedef struct pgpv_signed_userid_t { - pgpv_string_t userid; - PGPV_ARRAY(pgpv_signature_t, sigs); - uint8_t primary_userid; - uint8_t revoked; -} pgpv_signed_userid_t; - -typedef struct pgpv_signed_userattr_t { - pgpv_userattr_t userattr; - PGPV_ARRAY(pgpv_signature_t, sigs); - uint8_t revoked; -} pgpv_signed_userattr_t; - -typedef struct pgpv_signed_subkey_t { - pgpv_pubkey_t subkey; - pgpv_signature_t revoc_self_sig; - PGPV_ARRAY(pgpv_signature_t, sigs); -} pgpv_signed_subkey_t; - -typedef struct pgpv_primarykey_t { - pgpv_pubkey_t primary; - pgpv_signature_t revoc_self_sig; - PGPV_ARRAY(pgpv_signature_t, direct_sigs); - PGPV_ARRAY(pgpv_signed_userid_t, signed_userids); - PGPV_ARRAY(pgpv_signed_userattr_t, signed_userattrs); - PGPV_ARRAY(pgpv_signed_subkey_t, signed_subkeys); - size_t fmtsize; - uint8_t primary_userid; -} pgpv_primarykey_t; - -/* everything stems from this structure */ -typedef struct pgpv_t { - PGPV_ARRAY(pgpv_pkt_t, pkts); /* packet array */ - PGPV_ARRAY(pgpv_primarykey_t, primaries); /* array of primary keys */ - PGPV_ARRAY(pgpv_mem_t, areas); /* areas we read packets from */ - PGPV_ARRAY(size_t, datastarts); /* starts of data packets */ - size_t pkt; /* when parsing, current pkt number */ - const char *op; /* the operation we're doing */ -} pgpv_t; - -#define PGPV_REASON_LEN 128 - -/* when searching, we define a cursor, and fill in an array of subscripts */ -typedef struct pgpv_cursor_t { - pgpv_t *pgp; /* pointer to pgp tree */ - char *field; /* field we're searching on */ - char *op; /* operation we're doing */ - char *value; /* value we're searching for */ - void *ptr; /* for regexps etc */ - PGPV_ARRAY(uint32_t, found); /* array of matched subscripts */ - PGPV_ARRAY(size_t, datacookies); /* cookies to retrieve matched data */ - int64_t sigtime; /* time of signature */ - char why[PGPV_REASON_LEN]; /* reason for bad signature */ -} pgpv_cursor_t; - -#ifndef __BEGIN_DECLS -# if defined(__cplusplus) -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -# else -# define __BEGIN_DECLS -# define __END_DECLS -# endif -#endif - -__BEGIN_DECLS - -int pgpv_read_pubring(pgpv_t */*pgp*/, const void */*keyringfile/mem*/, ssize_t /*size*/); - -size_t pgpv_verify(pgpv_cursor_t */*cursor*/, pgpv_t */*pgp*/, const void */*mem/file*/, ssize_t /*size*/); -size_t pgpv_get_verified(pgpv_cursor_t */*cursor*/, size_t /*cookie*/, char **/*ret*/); - -size_t pgpv_get_entry(pgpv_t */*pgp*/, unsigned /*ent*/, char **/*ret*/); - -int pgpv_close(pgpv_t */*pgp*/); - -__END_DECLS - -#endif |