version 0.3.33
[fms.git] / libs / libtomcrypt / pk / asn1 / der / short_integer / der_encode_short_integer.c
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, tomstdenis@gmail.com, http://libtomcrypt.com
10  */
11 #include "tomcrypt.h"
12
13 /**
14   @file der_encode_short_integer.c
15   ASN.1 DER, encode an integer, Tom St Denis
16 */
17
18
19 #ifdef LTC_DER
20
21 /**
22   Store a short integer in the range (0,2^32-1)
23   @param num      The integer to encode
24   @param out      [out] The destination for the DER encoded integers
25   @param outlen   [in/out] The max size and resulting size of the DER encoded integers
26   @return CRYPT_OK if successful
27 */
28 int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen)
29 {  
30    unsigned long len, x, y, z;
31    int           err;
32    
33    LTC_ARGCHK(out    != NULL);
34    LTC_ARGCHK(outlen != NULL);
35
36    /* force to 32 bits */
37    num &= 0xFFFFFFFFUL;
38
39    /* find out how big this will be */
40    if ((err = der_length_short_integer(num, &len)) != CRYPT_OK) {
41       return err;
42    }
43
44    if (*outlen < len) {
45       *outlen = len;
46       return CRYPT_BUFFER_OVERFLOW;
47    }
48
49    /* get len of output */
50    z = 0;
51    y = num;
52    while (y) {
53      ++z;
54      y >>= 8;
55    }
56
57    /* handle zero */
58    if (z == 0) {
59       z = 1;
60    }
61
62    /* see if msb is set */
63    z += (num&(1UL<<((z<<3) - 1))) ? 1 : 0;
64
65    /* adjust the number so the msB is non-zero */
66    for (x = 0; (z <= 4) && (x < (4 - z)); x++) {
67       num <<= 8;
68    }
69
70    /* store header */
71    x = 0;
72    out[x++] = 0x02;
73    out[x++] = (unsigned char)z;
74
75    /* if 31st bit is set output a leading zero and decrement count */
76    if (z == 5) {
77       out[x++] = 0;
78       --z;
79    }
80
81    /* store values */
82    for (y = 0; y < z; y++) {
83       out[x++] = (unsigned char)((num >> 24) & 0xFF);
84       num    <<= 8;
85    }
86
87    /* we good */
88    *outlen = x;
89  
90    return CRYPT_OK;
91 }
92
93 #endif
94
95 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c,v $ */
96 /* $Revision: 1.7 $ */
97 /* $Date: 2006/12/04 21:34:03 $ */