[Opentnl-cvs] tnl/libtomcrypt/pk/asn1/der der_decode_integer.c,NONE,1.1 der_encode_integer.c,NONE,1.
Brought to you by:
mark_frohnmayer,
s_alanet
From: Mark F. <mar...@us...> - 2005-04-28 17:28:13
|
Update of /cvsroot/opentnl/tnl/libtomcrypt/pk/asn1/der In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26694/libtomcrypt/pk/asn1/der Added Files: der_decode_integer.c der_encode_integer.c der_get_multi_integer.c der_length_integer.c der_put_multi_integer.c Log Message: Updated to libtomcrypt 1.0.2 Not tested on linux or OS X --- NEW FILE: der_put_multi_integer.c --- /* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tom...@gm..., http://libtomcrypt.org */ #include <stdarg.h> #include "tomcrypt.h" /** @file der_put_multi_integer.c ASN.1 DER, store multiple integers, Tom St Denis */ #ifdef LTC_DER /* store multiple mp_ints in DER INTEGER format to the out, will not * overflow the length you give it [outlen] and store the number of * bytes used in [outlen] */ /** Store multiple mp_int integers one after another @param out [out] The destination for the DER encoded integers @param outlen [in/out] The max size and resulting size of the DER encoded integers @param num The first mp_int to encode @param ... A NULL terminated list of mp_ints to encode @return CRYPT_OK if successful */ int der_put_multi_integer(unsigned char *out, unsigned long *outlen, mp_int *num, ...) { va_list args; mp_int *next; unsigned long wrote, len; int err; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* setup va list */ next = num; len = *outlen; wrote = 0; va_start(args, num); while (next != NULL) { if ((err = der_encode_integer(next, out, outlen)) != CRYPT_OK) { va_end(args); return err; } wrote += *outlen; out += *outlen; len -= *outlen; *outlen = len; next = va_arg(args, mp_int*); } va_end(args); *outlen = wrote; return CRYPT_OK; } #endif --- NEW FILE: der_encode_integer.c --- /* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tom...@gm..., http://libtomcrypt.org */ #include "tomcrypt.h" /** @file der_encode_integer.c ASN.1 DER, encode an integer, Tom St Denis */ #ifdef LTC_DER /* Exports a positive bignum as DER format (upto 2^32 bytes in size) */ /** Store a mp_int integer @param num The first mp_int to encode @param out [out] The destination for the DER encoded integers @param outlen [in/out] The max size and resulting size of the DER encoded integers @return CRYPT_OK if successful */ int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) { unsigned long tmplen, x, y, z; int err, leading_zero; LTC_ARGCHK(num != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* find out how big this will be */ if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) { return err; } if (*outlen < tmplen) { return CRYPT_BUFFER_OVERFLOW; } /* we only need a leading zero if the msb of the first byte is one */ if ((mp_count_bits(num) & 7) == 7 || mp_iszero(num) == MP_YES) { leading_zero = 1; } else { leading_zero = 0; } /* get length of num in bytes (plus 1 since we force the msbyte to zero) */ y = mp_unsigned_bin_size(num) + leading_zero; /* now store initial data */ *out++ = 0x02; if (y < 128) { /* short form */ *out++ = (unsigned char)y; } else { /* long form (relies on y != 0) */ /* get length of length... ;-) */ x = y; z = 0; while (x) { ++z; x >>= 8; } /* store length of length */ *out++ = 0x80 | ((unsigned char)z); /* now store length */ /* first shift length up so msbyte != 0 */ x = y; while ((x & 0xFF000000) == 0) { x <<= 8; } /* now store length */ while (z--) { *out++ = (unsigned char)((x >> 24) & 0xFF); x <<= 8; } } /* now store msbyte of zero if num is non-zero */ if (leading_zero) { *out++ = 0x00; } /* if it's not zero store it as big endian */ if (mp_iszero(num) == MP_NO) { /* now store the mpint */ if ((err = mp_to_unsigned_bin(num, out)) != MP_OKAY) { return mpi_to_ltc_error(err); } } /* we good */ *outlen = tmplen; return CRYPT_OK; } #endif --- NEW FILE: der_decode_integer.c --- /* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tom...@gm..., http://libtomcrypt.org */ #include "tomcrypt.h" /** @file der_decode_integer.c ASN.1 DER, decode an integer, Tom St Denis */ #ifdef LTC_DER /* decodes a DER INTEGER in [in]. You have to tell this function * how many bytes are available [inlen]. It will then attempt to * read the INTEGER. If all goes well it stores the number of bytes * read in [inlen] and the number in [num]. */ /** Read a mp_int integer @param in The DER encoded data @param inlen [in] Size of the in data, [out] number of bytes read @param num The first mp_int to decode @return CRYPT_OK if successful */ int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num) { unsigned long tmplen, y, z; LTC_ARGCHK(num != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(inlen != NULL); /* save copy of max output size */ tmplen = *inlen; *inlen = 0; /* min DER INTEGER is 0x02 01 00 == 0 */ if (tmplen < (1 + 1 + 1)) { return CRYPT_INVALID_PACKET; } /* ok expect 0x02 when we AND with 0011 1111 [3F] */ if ((*in++ & 0x3F) != 0x02) { return CRYPT_INVALID_PACKET; } ++(*inlen); /* now decode the len stuff */ z = *in++; ++(*inlen); if ((z & 0x80) == 0x00) { /* short form */ /* will it overflow? */ if (*inlen + z > tmplen) { return CRYPT_INVALID_PACKET; } /* no so read it */ (*inlen) += z; return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, z)); } else { /* long form */ z &= 0x7F; /* will number of length bytes overflow? (or > 4) */ if (((*inlen + z) > tmplen) || (z > 4)) { return CRYPT_INVALID_PACKET; } /* now read it in */ y = 0; while (z--) { y = ((unsigned long)(*in++)) | (y << 8); ++(*inlen); } /* now will reading y bytes overrun? */ if ((*inlen + y) > tmplen) { return CRYPT_INVALID_PACKET; } /* no so read it */ (*inlen) += y; return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, y)); } } #endif --- NEW FILE: der_length_integer.c --- /* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tom...@gm..., http://libtomcrypt.org */ #include "tomcrypt.h" /** @file der_length_integer.c ASN.1 DER, get length of encoding, Tom St Denis */ #ifdef LTC_DER /** Gets length of DER encoding of num @param num The mp_int to get the size of @param outlen [out] The length of the DER encoding for the given integer @return CRYPT_OK if successful */ int der_length_integer(mp_int *num, unsigned long *outlen) { unsigned long z, len; int leading_zero; LTC_ARGCHK(num != NULL); LTC_ARGCHK(outlen != NULL); /* we only need a leading zero if the msb of the first byte is one */ if ((mp_count_bits(num) & 7) == 7 || mp_iszero(num) == MP_YES) { leading_zero = 1; } else { leading_zero = 0; } /* size for bignum */ z = len = leading_zero + mp_unsigned_bin_size(num); /* we need a 0x02 */ ++len; /* now we need a length */ if (z < 128) { /* short form */ ++len; } else { /* long form (relies on z != 0) */ ++len; while (z) { ++len; z >>= 8; } } *outlen = len; return CRYPT_OK; } #endif --- NEW FILE: der_get_multi_integer.c --- /* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tom...@gm..., http://libtomcrypt.org */ #include <stdarg.h> #include "tomcrypt.h" /** @file der_get_multi_integer.c ASN.1 DER, read multiple integers, Tom St Denis */ #ifdef LTC_DER /* will read multiple DER INTEGER encoded mp_ints from src * of upto [inlen] bytes. It will store the number of bytes * read back into [inlen]. */ /** Read multiple mp_int integers one after another @param src The DER encoded integers @param inlen [in] The length of the src buffer, [out] the amount of bytes read @param num The first mp_int to decode @param ... A NULL terminated list of mp_ints to decode @return CRYPT_OK if successful */ int der_get_multi_integer(const unsigned char *src, unsigned long *inlen, mp_int *num, ...) { va_list args; mp_int *next; unsigned long wrote, len; int err; LTC_ARGCHK(src != NULL); LTC_ARGCHK(inlen != NULL); /* setup va list */ next = num; len = *inlen; wrote = 0; va_start(args, num); while (next != NULL) { if ((err = der_decode_integer(src, inlen, next)) != CRYPT_OK) { va_end(args); return err; } wrote += *inlen; src += *inlen; len -= *inlen; *inlen = len; next = va_arg(args, mp_int*); } va_end(args); *inlen = wrote; return CRYPT_OK; } #endif |