source: trunk/third/moira/util/rsaref/r_encode.c @ 23095

Revision 23095, 7.6 KB checked in by ghudson, 16 years ago (diff)
Import the moira package from SIPB Debathena.
Line 
1/* R_ENCODE.C - RFC 1113 encoding and decoding routines
2 */
3
4/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
5     Inc., created 1991. All rights reserved.
6 */
7
8#include "global.h"
9#include "rsaref.h"
10
11/* RFC 1113 encoding:
12
13   Value Encoding  Value Encoding  Value Encoding  Value Encoding
14       0 A            17 R            34 i            51 z
15       1 B            18 S            35 j            52 0
16       2 C            19 T            36 k            53 1
17       3 D            20 U            37 l            54 2
18       4 E            21 V            38 m            55 3
19       5 F            22 W            39 n            56 4
20       6 G            23 X            40 o            57 5
21       7 H            24 Y            41 p            58 6
22       8 I            25 Z            42 q            59 7
23       9 J            26 a            43 r            60 8
24      10 K            27 b            44 s            61 9
25      11 L            28 c            45 t            62 +
26      12 M            29 d            46 u            63 /
27      13 N            30 e            47 v
28      14 O            31 f            48 w         (pad) =
29      15 P            32 g            49 x
30      16 Q            33 h            50 y
31*/
32#define ENCODING(i) \
33  (unsigned char)(((i) < 26) ? ((i) + 0x41) : \
34                  (((i) < 52) ? ((i) - 26 + 0x61) : \
35                   (((i) < 62) ? ((i) - 52 + 0x30) : \
36                    (((i) == 62) ? 0x2b : 0x2f))))
37#define ENCODING_PAD 0x3d
38
39#define IS_ENCODING(c) \
40  ((((c) >= 0x41) && ((c) <= 0x5a)) || \
41   (((c) >= 0x61) && ((c) <= 0x7a)) || \
42   (((c) >= 0x30) && ((c) <= 0x39)) || \
43   ((c) == 0x2b) || \
44   ((c) == 0x2f))
45
46/* assumes IS_ENCODING (c) == 1 */
47#define DECODING(c) \
48  (((c) == 0x2b) ? 62 : \
49   (((c) == 0x2f) ? 63 : \
50    (((c) <= 0x39) ? ((c) - 0x30 + 52) : \
51     (((c) <= 0x5a) ? ((c) - 0x41) : ((c) - 0x61 + 26)))))
52     
53static void EncodeQuantum PROTO_LIST ((unsigned char [4], unsigned char [3]));
54static int DecodeQuantum PROTO_LIST ((unsigned char [3], unsigned char [4]));
55static void EncodeLastQuantum
56  PROTO_LIST ((unsigned char [4], unsigned char *, unsigned int));
57static int DecodeLastQuantum
58  PROTO_LIST ((unsigned char *, unsigned int *, unsigned char [4]));
59
60/* This always returns 0.  It is an int function for future compatibility.
61 */
62int R_EncodePEMBlock (encodedBlock, encodedBlockLen, block, blockLen)
63unsigned char *encodedBlock;                               /* encoded block */
64unsigned int *encodedBlockLen;                   /* length of encoded block */
65unsigned char *block;                                              /* block */
66unsigned int blockLen;                                   /* length of block */
67{
68  unsigned int i, lastLen;
69 
70  if (blockLen < 1) {
71    *encodedBlockLen = 0;
72    return (0);
73  }
74 
75  for (i = 0; i < (blockLen-1)/3; i++)
76    EncodeQuantum (&encodedBlock[4*i], &block[3*i]);
77 
78  lastLen = blockLen - 3*i;
79  EncodeLastQuantum (&encodedBlock[4*i], &block[3*i], lastLen);
80  *encodedBlockLen = 4*i + 4;
81
82  return (0);
83}
84                   
85int R_DecodePEMBlock (block, blockLen, encodedBlock, encodedBlockLen)
86unsigned char *block;                                              /* block */
87unsigned int *blockLen;                                  /* length of block */
88unsigned char *encodedBlock;                               /* encoded block */
89unsigned int encodedBlockLen;                    /* length of encoded block */
90{
91  int status;
92  unsigned int i, lastLen;
93
94  if (encodedBlockLen % 4)
95    return (RE_ENCODING);
96 
97  if (encodedBlockLen < 1) {
98    *blockLen = 0;
99    return (0);
100  }
101 
102  for (i = 0; i < (encodedBlockLen-1)/4; i++)
103    if (status = DecodeQuantum (&block[3*i], &encodedBlock[4*i]))
104      return (status);
105   
106  if (status = DecodeLastQuantum (&block[3*i], &lastLen, &encodedBlock[4*i]))
107    return (status);
108
109  *blockLen = 3*i + lastLen;
110  return (0);
111}
112
113static void EncodeQuantum (encodedQuantum, quantum)
114unsigned char encodedQuantum[4];
115unsigned char quantum[3];
116{
117  UINT4 temp;
118  unsigned int a, b, c, d;
119 
120  temp = ((UINT4)quantum[0]) << 16;
121  temp |= ((UINT4)quantum[1]) << 8;
122  temp |= (UINT4)quantum[2];
123 
124  a = (unsigned int)((temp >> 18) & 0x3f);
125  b = (unsigned int)((temp >> 12) & 0x3f);
126  c = (unsigned int)((temp >> 6) & 0x3f);
127  d = (unsigned int)(temp & 0x3f);
128
129  encodedQuantum[0] = ENCODING (a);
130  encodedQuantum[1] = ENCODING (b);
131  encodedQuantum[2] = ENCODING (c);
132  encodedQuantum[3] = ENCODING (d);
133
134  /* Zeroize potentially sensitive information.
135   */
136  temp = 0;
137  a = b = c = d = 0;
138}
139
140static int DecodeQuantum (quantum, encodedQuantum)
141unsigned char quantum[3];
142unsigned char encodedQuantum[4];
143{
144  UINT4 temp;
145  unsigned int a, b, c, d;
146 
147  if (! IS_ENCODING (encodedQuantum[0]) ||
148      ! IS_ENCODING (encodedQuantum[1]) ||
149      ! IS_ENCODING (encodedQuantum[2]) ||
150      ! IS_ENCODING (encodedQuantum[3]))
151    return (RE_ENCODING);
152 
153  a = DECODING (encodedQuantum[0]);
154  b = DECODING (encodedQuantum[1]);
155  c = DECODING (encodedQuantum[2]);
156  d = DECODING (encodedQuantum[3]);
157 
158  temp = ((UINT4)a) << 18;
159  temp |= ((UINT4)b) << 12;
160  temp |= ((UINT4)c) << 6;
161  temp |= (UINT4)d;
162
163  quantum[0] = (unsigned char)(temp >> 16);
164  quantum[1] = (unsigned char)(temp >> 8);
165  quantum[2] = (unsigned char)temp;
166 
167  /* Zeroize potentially sensitive information.
168   */
169  temp = 0;
170  a = b = c = d = 0;
171
172  return (0);
173}
174
175static void EncodeLastQuantum (encodedQuantum, quantum, quantumLen)
176unsigned char encodedQuantum[4];
177unsigned char *quantum;
178unsigned int quantumLen;                                       /* 1, 2 or 3 */
179{
180  UINT4 temp;
181  unsigned int a, b, c, d;
182
183  temp = ((UINT4)quantum[0]) << 16;
184  if (quantumLen >= 2)
185    temp |= ((UINT4)quantum[1]) << 8;
186  if (quantumLen == 3)
187    temp |= ((UINT4)quantum[2]);
188 
189  a = (unsigned int)((temp >> 18) & 0x3f);
190  b = (unsigned int)((temp >> 12) & 0x3f);
191  if (quantumLen >= 2)
192    c = (unsigned int)((temp >> 6) & 0x3f);
193  if (quantumLen == 3)
194    d = (unsigned int)(temp & 0x3f);
195
196  encodedQuantum[0] = ENCODING (a);
197  encodedQuantum[1] = ENCODING (b);
198  if (quantumLen >= 2)
199    encodedQuantum[2] = ENCODING (c);
200  else
201    encodedQuantum[2] = ENCODING_PAD;
202  if (quantumLen == 3)
203    encodedQuantum[3] = ENCODING (d);
204  else
205    encodedQuantum[3] = ENCODING_PAD;
206
207  /* Zeroize potentially sensitive information.
208   */
209  temp = 0;
210  a = b = c = d = 0;
211}
212
213static int DecodeLastQuantum (quantum, quantumLen, encodedQuantum)
214unsigned char *quantum;
215unsigned int *quantumLen;                                      /* 1, 2 or 3 */
216unsigned char encodedQuantum[4];
217{
218  UINT4 temp;
219  unsigned int a, b, c, d;
220 
221  if (! IS_ENCODING (encodedQuantum[0]) ||
222      ! IS_ENCODING (encodedQuantum[1]) ||
223      (! IS_ENCODING (encodedQuantum[2]) &&
224       (encodedQuantum[2] != ENCODING_PAD)) ||
225      (! IS_ENCODING (encodedQuantum[3]) &&
226       (encodedQuantum[3] != ENCODING_PAD)))
227    return (RE_ENCODING);
228       
229  if (encodedQuantum[2] == ENCODING_PAD)
230    *quantumLen = 1;
231  else if (encodedQuantum[3] == ENCODING_PAD)
232    *quantumLen = 2;
233  else
234    *quantumLen = 3;
235 
236  a = DECODING (encodedQuantum[0]);
237  b = DECODING (encodedQuantum[1]);
238  if (*quantumLen >= 2)
239    c = DECODING (encodedQuantum[2]);
240  if (*quantumLen == 3)
241    d = DECODING (encodedQuantum[3]);
242 
243  temp = ((UINT4)a) << 18;
244  temp |= ((UINT4)b) << 12;
245  if (*quantumLen >= 2)
246    temp |= ((UINT4)c) << 6;
247  if (*quantumLen == 3)
248    temp |= ((UINT4)d);
249
250  quantum[0] = (unsigned char)(temp >> 16);
251  if (*quantumLen >= 2)
252    quantum[1] = (unsigned char)(temp >> 8);
253  if (*quantumLen == 3)
254    quantum[2] = (unsigned char)temp;
255 
256  /* Zeroize potentially sensitive information.
257   */
258  temp = 0;
259  a = b = c = d = 0;
260 
261  return (0);
262}
Note: See TracBrowser for help on using the repository browser.