1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3
4 #include "tomcrypt_private.h"
5
6 #ifdef LTC_PKCS_12
7
pkcs12_utf8_to_utf16(const unsigned char * in,unsigned long inlen,unsigned char * out,unsigned long * outlen)8 int pkcs12_utf8_to_utf16(const unsigned char *in, unsigned long inlen,
9 unsigned char *out, unsigned long *outlen) {
10 unsigned long len = 0;
11 const unsigned char* in_end = in + inlen;
12 const ulong32 offset[6] = {
13 0x00000000UL, 0x00003080UL, 0x000E2080UL,
14 0x03C82080UL, 0xFA082080UL, 0x82082080UL
15 };
16 int err = CRYPT_ERROR;
17
18 LTC_ARGCHK(in != NULL);
19 LTC_ARGCHK(out != NULL);
20 LTC_ARGCHK(outlen != NULL);
21
22 while (in < in_end) {
23 ulong32 ch = 0;
24 unsigned short extra = 0; /* 0 */
25 if (*in >= 192) extra++; /* 1 */
26 if (*in >= 224) extra++; /* 2 */
27 if (*in >= 240) extra++; /* 3 */
28 if (*in >= 248) extra++; /* 4 */
29 if (*in >= 252) extra++; /* 5 */
30 if (in + extra >= in_end) goto ERROR;
31 switch (extra) {
32 case 5: ch += *in++; ch <<= 6;
33 /* FALLTHROUGH */
34 case 4: ch += *in++; ch <<= 6;
35 /* FALLTHROUGH */
36 case 3: ch += *in++; ch <<= 6;
37 /* FALLTHROUGH */
38 case 2: ch += *in++; ch <<= 6;
39 /* FALLTHROUGH */
40 case 1: ch += *in++; ch <<= 6;
41 /* FALLTHROUGH */
42 case 0: ch += *in++;
43 default: break;
44 }
45 ch -= offset[extra];
46 if (ch > 0xFFFF) goto ERROR;
47 if (*outlen >= len + 2) {
48 out[len] = (unsigned short)((ch >> 8) & 0xFF);
49 out[len + 1] = (unsigned char)(ch & 0xFF);
50 }
51 len += 2;
52 }
53
54 err = len > *outlen ? CRYPT_BUFFER_OVERFLOW : CRYPT_OK;
55 *outlen = len;
56 ERROR:
57 return err;
58 }
59
60 #endif
61