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