Files
data-lite-c/Sources/DataLiteC/libtomcrypt/misc/pkcs12/pkcs12_utf8_to_utf16.c

60 lines
1.7 KiB
C

/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"
#ifdef LTC_PKCS_12
int pkcs12_utf8_to_utf16(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen) {
unsigned long len = 0;
const unsigned char* in_end = in + inlen;
const ulong32 offset[6] = {
0x00000000UL, 0x00003080UL, 0x000E2080UL,
0x03C82080UL, 0xFA082080UL, 0x82082080UL
};
int err = CRYPT_ERROR;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
while (in < in_end) {
ulong32 ch = 0;
unsigned short extra = 0; /* 0 */
if (*in >= 192) extra++; /* 1 */
if (*in >= 224) extra++; /* 2 */
if (*in >= 240) extra++; /* 3 */
if (*in >= 248) extra++; /* 4 */
if (*in >= 252) extra++; /* 5 */
if (in + extra >= in_end) goto ERROR;
switch (extra) {
case 5: ch += *in++; ch <<= 6;
/* FALLTHROUGH */
case 4: ch += *in++; ch <<= 6;
/* FALLTHROUGH */
case 3: ch += *in++; ch <<= 6;
/* FALLTHROUGH */
case 2: ch += *in++; ch <<= 6;
/* FALLTHROUGH */
case 1: ch += *in++; ch <<= 6;
/* FALLTHROUGH */
case 0: ch += *in++;
}
ch -= offset[extra];
if (ch > 0xFFFF) goto ERROR;
if (*outlen >= len + 2) {
out[len] = (unsigned short)((ch >> 8) & 0xFF);
out[len + 1] = (unsigned char)(ch & 0xFF);
}
len += 2;
}
err = len > *outlen ? CRYPT_BUFFER_OVERFLOW : CRYPT_OK;
*outlen = len;
ERROR:
return err;
}
#endif