1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3  *
4  * LibTomCrypt is a library that provides various cryptographic
5  * algorithms in a highly modular and flexible manner.
6  *
7  * The library is free for all purposes without any express
8  * guarantee it works.
9  */
10 
11 #include "tomcrypt_private.h"
12 
13 #ifdef LTC_PKCS_12
14 
pkcs12_utf8_to_utf16(const unsigned char * in,unsigned long inlen,unsigned char * out,unsigned long * outlen)15 int pkcs12_utf8_to_utf16(const unsigned char *in,  unsigned long  inlen,
16                                unsigned char *out, unsigned long *outlen) {
17    unsigned long len = 0;
18    const unsigned char* in_end = in + inlen;
19    const ulong32 offset[6] = {
20       0x00000000UL, 0x00003080UL, 0x000E2080UL,
21       0x03C82080UL, 0xFA082080UL, 0x82082080UL
22    };
23    int err = CRYPT_ERROR;
24 
25    LTC_ARGCHK(in     != NULL);
26    LTC_ARGCHK(out    != NULL);
27    LTC_ARGCHK(outlen != NULL);
28 
29    while (in < in_end) {
30       ulong32 ch = 0;
31       unsigned short extra = 0; /* 0 */
32       if (*in >= 192) extra++;  /* 1 */
33       if (*in >= 224) extra++;  /* 2 */
34       if (*in >= 240) extra++;  /* 3 */
35       if (*in >= 248) extra++;  /* 4 */
36       if (*in >= 252) extra++;  /* 5 */
37       if (in + extra >= in_end) goto ERROR;
38       switch (extra) {
39          case 5: ch += *in++; ch <<= 6;
40          /* FALLTHROUGH */
41          case 4: ch += *in++; ch <<= 6;
42          /* FALLTHROUGH */
43          case 3: ch += *in++; ch <<= 6;
44          /* FALLTHROUGH */
45          case 2: ch += *in++; ch <<= 6;
46          /* FALLTHROUGH */
47          case 1: ch += *in++; ch <<= 6;
48          /* FALLTHROUGH */
49          case 0: ch += *in++;
50       }
51       ch -= offset[extra];
52       if (ch > 0xFFFF) goto ERROR;
53       if (*outlen >= len + 2) {
54          out[len] = (unsigned short)((ch >> 8) & 0xFF);
55          out[len + 1] = (unsigned char)(ch & 0xFF);
56       }
57       len += 2;
58    }
59 
60    err = len > *outlen ? CRYPT_BUFFER_OVERFLOW : CRYPT_OK;
61    *outlen = len;
62 ERROR:
63    return err;
64 }
65 
66 #endif
67 
68 /* ref:         $Format:%D$ */
69 /* git commit:  $Format:%H$ */
70 /* commit time: $Format:%ai$ */
71