comparison src/pk/asn1/der/der_encode_integer.c @ 191:1c15b283127b libtomcrypt-orig

Import of libtomcrypt 1.02 with manual path rename rearrangement etc
author Matt Johnston <matt@ucc.asn.au>
date Fri, 06 May 2005 13:23:02 +0000
parents
children
comparison
equal deleted inserted replaced
143:5d99163f7e32 191:1c15b283127b
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org
10 */
11 #include "tomcrypt.h"
12
13 /**
14 @file der_encode_integer.c
15 ASN.1 DER, encode an integer, Tom St Denis
16 */
17
18
19 #ifdef LTC_DER
20
21 /* Exports a positive bignum as DER format (upto 2^32 bytes in size) */
22 /**
23 Store a mp_int integer
24 @param num The first mp_int to encode
25 @param out [out] The destination for the DER encoded integers
26 @param outlen [in/out] The max size and resulting size of the DER encoded integers
27 @return CRYPT_OK if successful
28 */
29 int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen)
30 {
31 unsigned long tmplen, x, y, z;
32 int err, leading_zero;
33
34 LTC_ARGCHK(num != NULL);
35 LTC_ARGCHK(out != NULL);
36 LTC_ARGCHK(outlen != NULL);
37
38 /* find out how big this will be */
39 if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) {
40 return err;
41 }
42
43 if (*outlen < tmplen) {
44 return CRYPT_BUFFER_OVERFLOW;
45 }
46
47 /* we only need a leading zero if the msb of the first byte is one */
48 if ((mp_count_bits(num) & 7) == 7 || mp_iszero(num) == MP_YES) {
49 leading_zero = 1;
50 } else {
51 leading_zero = 0;
52 }
53
54 /* get length of num in bytes (plus 1 since we force the msbyte to zero) */
55 y = mp_unsigned_bin_size(num) + leading_zero;
56
57 /* now store initial data */
58 *out++ = 0x02;
59 if (y < 128) {
60 /* short form */
61 *out++ = (unsigned char)y;
62 } else {
63 /* long form (relies on y != 0) */
64
65 /* get length of length... ;-) */
66 x = y;
67 z = 0;
68 while (x) {
69 ++z;
70 x >>= 8;
71 }
72
73 /* store length of length */
74 *out++ = 0x80 | ((unsigned char)z);
75
76 /* now store length */
77
78 /* first shift length up so msbyte != 0 */
79 x = y;
80 while ((x & 0xFF000000) == 0) {
81 x <<= 8;
82 }
83
84 /* now store length */
85 while (z--) {
86 *out++ = (unsigned char)((x >> 24) & 0xFF);
87 x <<= 8;
88 }
89 }
90
91 /* now store msbyte of zero if num is non-zero */
92 if (leading_zero) {
93 *out++ = 0x00;
94 }
95
96 /* if it's not zero store it as big endian */
97 if (mp_iszero(num) == MP_NO) {
98 /* now store the mpint */
99 if ((err = mp_to_unsigned_bin(num, out)) != MP_OKAY) {
100 return mpi_to_ltc_error(err);
101 }
102 }
103
104 /* we good */
105 *outlen = tmplen;
106 return CRYPT_OK;
107 }
108
109 #endif