|
|
1.1 root 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:
53: static void EncodeQuantum PROTO_LIST ((unsigned char [4], unsigned char [3]));
54: static int DecodeQuantum PROTO_LIST ((unsigned char [3], unsigned char [4]));
55: static void EncodeLastQuantum
56: PROTO_LIST ((unsigned char [4], unsigned char *, unsigned int));
57: static 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: */
62: int R_EncodePEMBlock (encodedBlock, encodedBlockLen, block, blockLen)
63: unsigned char *encodedBlock; /* encoded block */
64: unsigned int *encodedBlockLen; /* length of encoded block */
65: unsigned char *block; /* block */
66: unsigned 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:
85: int R_DecodePEMBlock (block, blockLen, encodedBlock, encodedBlockLen)
86: unsigned char *block; /* block */
87: unsigned int *blockLen; /* length of block */
88: unsigned char *encodedBlock; /* encoded block */
89: unsigned 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:
113: static void EncodeQuantum (encodedQuantum, quantum)
114: unsigned char encodedQuantum[4];
115: unsigned 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:
140: static int DecodeQuantum (quantum, encodedQuantum)
141: unsigned char quantum[3];
142: unsigned 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:
175: static void EncodeLastQuantum (encodedQuantum, quantum, quantumLen)
176: unsigned char encodedQuantum[4];
177: unsigned char *quantum;
178: unsigned 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:
213: static int DecodeLastQuantum (quantum, quantumLen, encodedQuantum)
214: unsigned char *quantum;
215: unsigned int *quantumLen; /* 1, 2 or 3 */
216: unsigned 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.