Mercurial > dropbear
comparison libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c @ 399:a707e6148060
merge of '5fdf69ca60d1683cdd9f4c2595134bed26394834'
and '6b61c50f4cf888bea302ac8fcf5dbb573b443251'
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 03 Feb 2007 08:20:34 +0000 |
parents | 0cbe8f6dbf9e |
children | f849a5ca2efc |
comparison
equal
deleted
inserted
replaced
394:17d097fc111c | 399:a707e6148060 |
---|---|
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.com | |
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(void *num, unsigned char *out, unsigned long *outlen) | |
30 { | |
31 unsigned long tmplen, y; | |
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 *outlen = tmplen; | |
45 return CRYPT_BUFFER_OVERFLOW; | |
46 } | |
47 | |
48 if (mp_cmp_d(num, 0) != LTC_MP_LT) { | |
49 /* we only need a leading zero if the msb of the first byte is one */ | |
50 if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { | |
51 leading_zero = 1; | |
52 } else { | |
53 leading_zero = 0; | |
54 } | |
55 | |
56 /* get length of num in bytes (plus 1 since we force the msbyte to zero) */ | |
57 y = mp_unsigned_bin_size(num) + leading_zero; | |
58 } else { | |
59 leading_zero = 0; | |
60 y = mp_count_bits(num); | |
61 y = y + (8 - (y & 7)); | |
62 y = y >> 3; | |
63 if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --y; | |
64 } | |
65 | |
66 /* now store initial data */ | |
67 *out++ = 0x02; | |
68 if (y < 128) { | |
69 /* short form */ | |
70 *out++ = (unsigned char)y; | |
71 } else if (y < 256) { | |
72 *out++ = 0x81; | |
73 *out++ = (unsigned char)y; | |
74 } else if (y < 65536UL) { | |
75 *out++ = 0x82; | |
76 *out++ = (unsigned char)((y>>8)&255); | |
77 *out++ = (unsigned char)y; | |
78 } else if (y < 16777216UL) { | |
79 *out++ = 0x83; | |
80 *out++ = (unsigned char)((y>>16)&255); | |
81 *out++ = (unsigned char)((y>>8)&255); | |
82 *out++ = (unsigned char)y; | |
83 } else { | |
84 return CRYPT_INVALID_ARG; | |
85 } | |
86 | |
87 /* now store msbyte of zero if num is non-zero */ | |
88 if (leading_zero) { | |
89 *out++ = 0x00; | |
90 } | |
91 | |
92 /* if it's not zero store it as big endian */ | |
93 if (mp_cmp_d(num, 0) == LTC_MP_GT) { | |
94 /* now store the mpint */ | |
95 if ((err = mp_to_unsigned_bin(num, out)) != CRYPT_OK) { | |
96 return err; | |
97 } | |
98 } else if (mp_iszero(num) != LTC_MP_YES) { | |
99 void *tmp; | |
100 | |
101 /* negative */ | |
102 if (mp_init(&tmp) != CRYPT_OK) { | |
103 return CRYPT_MEM; | |
104 } | |
105 | |
106 /* 2^roundup and subtract */ | |
107 y = mp_count_bits(num); | |
108 y = y + (8 - (y & 7)); | |
109 if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) y -= 8; | |
110 if (mp_2expt(tmp, y) != CRYPT_OK || mp_add(tmp, num, tmp) != CRYPT_OK) { | |
111 mp_clear(tmp); | |
112 return CRYPT_MEM; | |
113 } | |
114 if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) { | |
115 mp_clear(tmp); | |
116 return err; | |
117 } | |
118 mp_clear(tmp); | |
119 } | |
120 | |
121 /* we good */ | |
122 *outlen = tmplen; | |
123 return CRYPT_OK; | |
124 } | |
125 | |
126 #endif | |
127 | |
128 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c,v $ */ | |
129 /* $Revision: 1.8 $ */ | |
130 /* $Date: 2006/12/04 21:34:03 $ */ |