mirror of
https://github.com/cryb-to/cryb-to.git
synced 2024-11-25 15:15:42 +00:00
262 lines
7.6 KiB
C
262 lines
7.6 KiB
C
/* R_ENCODE.C - RFC 1113 encoding and decoding routines
|
|
*/
|
|
|
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
|
Inc., created 1991. All rights reserved.
|
|
*/
|
|
|
|
#include "global.h"
|
|
#include "rsaref.h"
|
|
|
|
/* RFC 1113 encoding:
|
|
|
|
Value Encoding Value Encoding Value Encoding Value Encoding
|
|
0 A 17 R 34 i 51 z
|
|
1 B 18 S 35 j 52 0
|
|
2 C 19 T 36 k 53 1
|
|
3 D 20 U 37 l 54 2
|
|
4 E 21 V 38 m 55 3
|
|
5 F 22 W 39 n 56 4
|
|
6 G 23 X 40 o 57 5
|
|
7 H 24 Y 41 p 58 6
|
|
8 I 25 Z 42 q 59 7
|
|
9 J 26 a 43 r 60 8
|
|
10 K 27 b 44 s 61 9
|
|
11 L 28 c 45 t 62 +
|
|
12 M 29 d 46 u 63 /
|
|
13 N 30 e 47 v
|
|
14 O 31 f 48 w (pad) =
|
|
15 P 32 g 49 x
|
|
16 Q 33 h 50 y
|
|
*/
|
|
#define ENCODING(i) \
|
|
(unsigned char)(((i) < 26) ? ((i) + 0x41) : \
|
|
(((i) < 52) ? ((i) - 26 + 0x61) : \
|
|
(((i) < 62) ? ((i) - 52 + 0x30) : \
|
|
(((i) == 62) ? 0x2b : 0x2f))))
|
|
#define ENCODING_PAD 0x3d
|
|
|
|
#define IS_ENCODING(c) \
|
|
((((c) >= 0x41) && ((c) <= 0x5a)) || \
|
|
(((c) >= 0x61) && ((c) <= 0x7a)) || \
|
|
(((c) >= 0x30) && ((c) <= 0x39)) || \
|
|
((c) == 0x2b) || \
|
|
((c) == 0x2f))
|
|
|
|
/* assumes IS_ENCODING (c) == 1 */
|
|
#define DECODING(c) \
|
|
(((c) == 0x2b) ? 62 : \
|
|
(((c) == 0x2f) ? 63 : \
|
|
(((c) <= 0x39) ? ((c) - 0x30 + 52) : \
|
|
(((c) <= 0x5a) ? ((c) - 0x41) : ((c) - 0x61 + 26)))))
|
|
|
|
static void EncodeQuantum PROTO_LIST ((unsigned char [4], unsigned char [3]));
|
|
static int DecodeQuantum PROTO_LIST ((unsigned char [3], unsigned char [4]));
|
|
static void EncodeLastQuantum
|
|
PROTO_LIST ((unsigned char [4], unsigned char *, unsigned int));
|
|
static int DecodeLastQuantum
|
|
PROTO_LIST ((unsigned char *, unsigned int *, unsigned char [4]));
|
|
|
|
/* This always returns 0. It is an int function for future compatibility.
|
|
*/
|
|
int R_EncodePEMBlock (encodedBlock, encodedBlockLen, block, blockLen)
|
|
unsigned char *encodedBlock; /* encoded block */
|
|
unsigned int *encodedBlockLen; /* length of encoded block */
|
|
unsigned char *block; /* block */
|
|
unsigned int blockLen; /* length of block */
|
|
{
|
|
unsigned int i, lastLen;
|
|
|
|
if (blockLen < 1) {
|
|
*encodedBlockLen = 0;
|
|
return (0);
|
|
}
|
|
|
|
for (i = 0; i < (blockLen-1)/3; i++)
|
|
EncodeQuantum (&encodedBlock[4*i], &block[3*i]);
|
|
|
|
lastLen = blockLen - 3*i;
|
|
EncodeLastQuantum (&encodedBlock[4*i], &block[3*i], lastLen);
|
|
*encodedBlockLen = 4*i + 4;
|
|
|
|
return (0);
|
|
}
|
|
|
|
int R_DecodePEMBlock (block, blockLen, encodedBlock, encodedBlockLen)
|
|
unsigned char *block; /* block */
|
|
unsigned int *blockLen; /* length of block */
|
|
unsigned char *encodedBlock; /* encoded block */
|
|
unsigned int encodedBlockLen; /* length of encoded block */
|
|
{
|
|
int status;
|
|
unsigned int i, lastLen;
|
|
|
|
if (encodedBlockLen % 4)
|
|
return (RE_ENCODING);
|
|
|
|
if (encodedBlockLen < 1) {
|
|
*blockLen = 0;
|
|
return (0);
|
|
}
|
|
|
|
for (i = 0; i < (encodedBlockLen-1)/4; i++)
|
|
if ((status = DecodeQuantum (&block[3*i], &encodedBlock[4*i])))
|
|
return (status);
|
|
|
|
if ((status = DecodeLastQuantum (&block[3*i], &lastLen, &encodedBlock[4*i])))
|
|
return (status);
|
|
|
|
*blockLen = 3*i + lastLen;
|
|
return (0);
|
|
}
|
|
|
|
static void EncodeQuantum (encodedQuantum, quantum)
|
|
unsigned char encodedQuantum[4];
|
|
unsigned char quantum[3];
|
|
{
|
|
UINT4 temp;
|
|
unsigned int a, b, c, d;
|
|
|
|
temp = ((UINT4)quantum[0]) << 16;
|
|
temp |= ((UINT4)quantum[1]) << 8;
|
|
temp |= (UINT4)quantum[2];
|
|
|
|
a = (unsigned int)((temp >> 18) & 0x3f);
|
|
b = (unsigned int)((temp >> 12) & 0x3f);
|
|
c = (unsigned int)((temp >> 6) & 0x3f);
|
|
d = (unsigned int)(temp & 0x3f);
|
|
|
|
encodedQuantum[0] = ENCODING (a);
|
|
encodedQuantum[1] = ENCODING (b);
|
|
encodedQuantum[2] = ENCODING (c);
|
|
encodedQuantum[3] = ENCODING (d);
|
|
|
|
/* Zeroize potentially sensitive information.
|
|
*/
|
|
temp = 0;
|
|
a = b = c = d = 0;
|
|
}
|
|
|
|
static int DecodeQuantum (quantum, encodedQuantum)
|
|
unsigned char quantum[3];
|
|
unsigned char encodedQuantum[4];
|
|
{
|
|
UINT4 temp;
|
|
unsigned int a, b, c, d;
|
|
|
|
if (! IS_ENCODING (encodedQuantum[0]) ||
|
|
! IS_ENCODING (encodedQuantum[1]) ||
|
|
! IS_ENCODING (encodedQuantum[2]) ||
|
|
! IS_ENCODING (encodedQuantum[3]))
|
|
return (RE_ENCODING);
|
|
|
|
a = DECODING (encodedQuantum[0]);
|
|
b = DECODING (encodedQuantum[1]);
|
|
c = DECODING (encodedQuantum[2]);
|
|
d = DECODING (encodedQuantum[3]);
|
|
|
|
temp = ((UINT4)a) << 18;
|
|
temp |= ((UINT4)b) << 12;
|
|
temp |= ((UINT4)c) << 6;
|
|
temp |= (UINT4)d;
|
|
|
|
quantum[0] = (unsigned char)(temp >> 16);
|
|
quantum[1] = (unsigned char)(temp >> 8);
|
|
quantum[2] = (unsigned char)temp;
|
|
|
|
/* Zeroize potentially sensitive information.
|
|
*/
|
|
temp = 0;
|
|
a = b = c = d = 0;
|
|
|
|
return (0);
|
|
}
|
|
|
|
static void EncodeLastQuantum (encodedQuantum, quantum, quantumLen)
|
|
unsigned char encodedQuantum[4];
|
|
unsigned char *quantum;
|
|
unsigned int quantumLen; /* 1, 2 or 3 */
|
|
{
|
|
UINT4 temp;
|
|
unsigned int a, b, c = 0, d = 0;
|
|
|
|
temp = ((UINT4)quantum[0]) << 16;
|
|
if (quantumLen >= 2)
|
|
temp |= ((UINT4)quantum[1]) << 8;
|
|
if (quantumLen == 3)
|
|
temp |= ((UINT4)quantum[2]);
|
|
|
|
a = (unsigned int)((temp >> 18) & 0x3f);
|
|
b = (unsigned int)((temp >> 12) & 0x3f);
|
|
if (quantumLen >= 2)
|
|
c = (unsigned int)((temp >> 6) & 0x3f);
|
|
if (quantumLen == 3)
|
|
d = (unsigned int)(temp & 0x3f);
|
|
|
|
encodedQuantum[0] = ENCODING (a);
|
|
encodedQuantum[1] = ENCODING (b);
|
|
if (quantumLen >= 2)
|
|
encodedQuantum[2] = ENCODING (c);
|
|
else
|
|
encodedQuantum[2] = ENCODING_PAD;
|
|
if (quantumLen == 3)
|
|
encodedQuantum[3] = ENCODING (d);
|
|
else
|
|
encodedQuantum[3] = ENCODING_PAD;
|
|
|
|
/* Zeroize potentially sensitive information.
|
|
*/
|
|
temp = 0;
|
|
a = b = c = d = 0;
|
|
}
|
|
|
|
static int DecodeLastQuantum (quantum, quantumLen, encodedQuantum)
|
|
unsigned char *quantum;
|
|
unsigned int *quantumLen; /* 1, 2 or 3 */
|
|
unsigned char encodedQuantum[4];
|
|
{
|
|
UINT4 temp;
|
|
unsigned int a, b, c = 0, d = 0;
|
|
|
|
if (! IS_ENCODING (encodedQuantum[0]) ||
|
|
! IS_ENCODING (encodedQuantum[1]) ||
|
|
(! IS_ENCODING (encodedQuantum[2]) &&
|
|
(encodedQuantum[2] != ENCODING_PAD)) ||
|
|
(! IS_ENCODING (encodedQuantum[3]) &&
|
|
(encodedQuantum[3] != ENCODING_PAD)))
|
|
return (RE_ENCODING);
|
|
|
|
if (encodedQuantum[2] == ENCODING_PAD)
|
|
*quantumLen = 1;
|
|
else if (encodedQuantum[3] == ENCODING_PAD)
|
|
*quantumLen = 2;
|
|
else
|
|
*quantumLen = 3;
|
|
|
|
a = DECODING (encodedQuantum[0]);
|
|
b = DECODING (encodedQuantum[1]);
|
|
if (*quantumLen >= 2)
|
|
c = DECODING (encodedQuantum[2]);
|
|
if (*quantumLen == 3)
|
|
d = DECODING (encodedQuantum[3]);
|
|
|
|
temp = ((UINT4)a) << 18;
|
|
temp |= ((UINT4)b) << 12;
|
|
if (*quantumLen >= 2)
|
|
temp |= ((UINT4)c) << 6;
|
|
if (*quantumLen == 3)
|
|
temp |= ((UINT4)d);
|
|
|
|
quantum[0] = (unsigned char)(temp >> 16);
|
|
if (*quantumLen >= 2)
|
|
quantum[1] = (unsigned char)(temp >> 8);
|
|
if (*quantumLen == 3)
|
|
quantum[2] = (unsigned char)temp;
|
|
|
|
/* Zeroize potentially sensitive information.
|
|
*/
|
|
temp = 0;
|
|
a = b = c = d = 0;
|
|
|
|
return (0);
|
|
}
|