1 /* R_ENCODE.C - RFC 1113 encoding and decoding routines
4 /* Copyright (C) RSA Laboratories, a division of RSA Data Security,
5 Inc., created 1991. All rights reserved.
13 Value Encoding Value Encoding Value Encoding Value Encoding
28 14 O 31 f 48 w (pad) =
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
39 #define IS_ENCODING(c) \
40 ((((c) >= 0x41) && ((c) <= 0x5a)) || \
41 (((c) >= 0x61) && ((c) <= 0x7a)) || \
42 (((c) >= 0x30) && ((c) <= 0x39)) || \
46 /* assumes IS_ENCODING (c) == 1 */
48 (((c) == 0x2b) ? 62 : \
49 (((c) == 0x2f) ? 63 : \
50 (((c) <= 0x39) ? ((c) - 0x30 + 52) : \
51 (((c) <= 0x5a) ? ((c) - 0x41) : ((c) - 0x61 + 26)))))
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]));
60 /* This always returns 0. It is an int function for future compatibility.
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 */
68 unsigned int i, lastLen;
75 for (i = 0; i < (blockLen-1)/3; i++)
76 EncodeQuantum (&encodedBlock[4*i], &block[3*i]);
78 lastLen = blockLen - 3*i;
79 EncodeLastQuantum (&encodedBlock[4*i], &block[3*i], lastLen);
80 *encodedBlockLen = 4*i + 4;
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 */
92 unsigned int i, lastLen;
94 if (encodedBlockLen % 4)
97 if (encodedBlockLen < 1) {
102 for (i = 0; i < (encodedBlockLen-1)/4; i++)
103 if (status = DecodeQuantum (&block[3*i], &encodedBlock[4*i]))
106 if (status = DecodeLastQuantum (&block[3*i], &lastLen, &encodedBlock[4*i]))
109 *blockLen = 3*i + lastLen;
113 static void EncodeQuantum (encodedQuantum, quantum)
114 unsigned char encodedQuantum[4];
115 unsigned char quantum[3];
118 unsigned int a, b, c, d;
120 temp = ((UINT4)quantum[0]) << 16;
121 temp |= ((UINT4)quantum[1]) << 8;
122 temp |= (UINT4)quantum[2];
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);
129 encodedQuantum[0] = ENCODING (a);
130 encodedQuantum[1] = ENCODING (b);
131 encodedQuantum[2] = ENCODING (c);
132 encodedQuantum[3] = ENCODING (d);
134 /* Zeroize potentially sensitive information.
140 static int DecodeQuantum (quantum, encodedQuantum)
141 unsigned char quantum[3];
142 unsigned char encodedQuantum[4];
145 unsigned int a, b, c, d;
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);
153 a = DECODING (encodedQuantum[0]);
154 b = DECODING (encodedQuantum[1]);
155 c = DECODING (encodedQuantum[2]);
156 d = DECODING (encodedQuantum[3]);
158 temp = ((UINT4)a) << 18;
159 temp |= ((UINT4)b) << 12;
160 temp |= ((UINT4)c) << 6;
163 quantum[0] = (unsigned char)(temp >> 16);
164 quantum[1] = (unsigned char)(temp >> 8);
165 quantum[2] = (unsigned char)temp;
167 /* Zeroize potentially sensitive information.
175 static void EncodeLastQuantum (encodedQuantum, quantum, quantumLen)
176 unsigned char encodedQuantum[4];
177 unsigned char *quantum;
178 unsigned int quantumLen; /* 1, 2 or 3 */
181 unsigned int a, b, c, d;
183 temp = ((UINT4)quantum[0]) << 16;
185 temp |= ((UINT4)quantum[1]) << 8;
187 temp |= ((UINT4)quantum[2]);
189 a = (unsigned int)((temp >> 18) & 0x3f);
190 b = (unsigned int)((temp >> 12) & 0x3f);
192 c = (unsigned int)((temp >> 6) & 0x3f);
194 d = (unsigned int)(temp & 0x3f);
196 encodedQuantum[0] = ENCODING (a);
197 encodedQuantum[1] = ENCODING (b);
199 encodedQuantum[2] = ENCODING (c);
201 encodedQuantum[2] = ENCODING_PAD;
203 encodedQuantum[3] = ENCODING (d);
205 encodedQuantum[3] = ENCODING_PAD;
207 /* Zeroize potentially sensitive information.
213 static int DecodeLastQuantum (quantum, quantumLen, encodedQuantum)
214 unsigned char *quantum;
215 unsigned int *quantumLen; /* 1, 2 or 3 */
216 unsigned char encodedQuantum[4];
219 unsigned int a, b, c, d;
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);
229 if (encodedQuantum[2] == ENCODING_PAD)
231 else if (encodedQuantum[3] == ENCODING_PAD)
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]);
243 temp = ((UINT4)a) << 18;
244 temp |= ((UINT4)b) << 12;
245 if (*quantumLen >= 2)
246 temp |= ((UINT4)c) << 6;
247 if (*quantumLen == 3)
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;
256 /* Zeroize potentially sensitive information.