/* $OpenXM: OpenXM/src/ox_ntl/crypt/radix/radix64.c,v 1.1 2004/01/12 14:52:18 iwane Exp $ */ /* RFC 2440 */ #include "radix64.h" #define CRC24_INIT 0xb704ceL #define CRC24_POLY 0x1864cfbL crc24 crc_octets(const unsigned char *octets, size_t len) { crc24 crc = CRC24_INIT; int i; while (len--) { crc ^= (*octets++) << 16; for (i = 0; i < 8; i++) { crc <<= 1; if (crc & 0x1000000) { crc ^= CRC24_POLY; } } } return (crc & 0xffffffL); } static const char *RADIX_STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; #define RADIX64_CONV(data, x) \ do { \ s[0] = (data[0] >> 2) & 0x3f; \ s[1] = ((data[0] & 0x3) << 4) | ((data[1] & 0xff) >> 4); \ s[2] = ((data[1] & 0xf) << 2) | ((data[2] & 0xff) >> 6); \ s[3] = data[2] & 0x3f; \ } while (0) #define radix64_conv(data, x) RADIX64_CONV((data), (x)) int radix64_enc(const unsigned char *data, int datalen, unsigned char *buf, int buflen) { int i, j, n = 0, m; int s[4]; char x[3] = {'\0'}; /* parameter check */ for (i = 0; i + 2 < datalen; i += 3) { radix64_conv(data + i, s); for (j = 0; j < 4; j++) buf[n++] = RADIX_STR[s[j]]; if (n % 76 == 0) buf[n++] = '\n'; } switch (datalen % 3) { case 0: goto _END; case 2: x[1] = data[i + 1]; case 1: x[0] = data[i]; break; } radix64_conv(x, s); m = 3 - datalen % 3; for (j = 0; j < datalen % 3 + 1; j++) buf[n++] = RADIX_STR[s[j]]; if (n % 76 == 0) buf[n++] = '\n'; for (j = 0; j < 3 - datalen % 3; j++) buf[n++] = '='; _END: buf[n] = '\0'; return (n); } int radix64_dec(const unsigned char *data, int datalen, unsigned char *buf, int buflen) { int i, j, n = 0; unsigned char m[4]; unsigned char alf[128] = {'\0'}; for (i = 0; i < 26; i++) { alf['A' + i] = i + 1; alf['a' + i] = i + 26 + 1; } for (i = 0; i < 10; i++) alf['0' + i] = 52 + i + 1; alf['+'] = 62 + 1; alf['/'] = 63 + 1; j = 0; for (i = 0; i < datalen; i++) { if (data[i] > sizeof(alf)) continue; if (data[i] == '=') break; if (alf[data[i]] == 0) continue; m[j++] = alf[data[i]] - 1; if (j == 4) { buf[n++] = (0x3f & m[0]) << 2 | ((m[1] >> 4) & 0x3); buf[n++] = ((m[1] << 4) & 0xf0) | ((m[2] & 0xfc) >> 2); buf[n++] = ((m[2] & 0x3) << 6) | (m[3] & 0x3f); j = 0; } } if (j != 0) { for (i = j; i < 4; i++) m[i] = '\0'; buf[n++] = (0x3f & m[0]) << 2 | ((m[1] >> 4) & 0x3); buf[n++] = ((m[1] << 4) & 0xf0) | ((m[2] & 0xfc) >> 2); buf[n++] = ((m[2] & 0x3) << 6) | (m[3] & 0x3f); n = n - 4 + j; } return (n); } #ifdef RADIX64_DEBUG int main() { int n; int m = 0, i, len; int x = 1000; char str[1024], buf[1024]; char *a = " yDgBO22WxBHv7O8X7O/jygAEzol56iUKiXmV+XmpCtmpqQUKiQrFqclFqUDBovzS\n vBSFjNSiVHsuAA==\n"; m=0; str[m++] = '\x14'; str[m++] = '\xfb'; str[m++] = '\x9c'; str[m++] = '\x03'; str[m++] = '\xd9'; str[m++] = '\x7e'; radix64_enc(str, m, buf, x); printf("%s\n", buf); radix64_enc(str, m - 1, buf, x); printf("%s\n", buf); radix64_enc(str, m - 2, buf, x); printf("%s\n", buf); len = radix64_dec(a, strlen(a), buf, x); printf("dec=%d\n0x", m); for (i = 0; i < m; i++) printf("%02x", buf[i] & 0xff); printf("\n\n"); m = radix64_enc(buf, m, str, x); for (i = 0; i < 80; i++) printf("%d", i % 10); printf("\n"); printf(" %s\n", str); printf("%s\n", a); m = crc_octets(buf, len); str[0] = (m >> 16) & 0xff; str[1] = (m >> 8) & 0xff; str[2] = m & 0xff; radix64_enc(str, 3, buf, x); printf(" %s : %06x\n", buf, m); return (0); } #endif /* RADIX64_DEBUG */