/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */

#include "tomcrypt_private.h"

/**
   @file base16_encode.c
   Base16/Hex encode a string, Steffen Jaeckel
*/

#ifdef LTC_BASE16

/**
   Base16 encode a buffer
   @param in       The input buffer to encode
   @param inlen    The length of the input buffer
   @param out      [out] The destination of the Base16 encoded data
   @param outlen   [in/out] The max size and resulting size of the encoded data
   @param options  Output 'a-f' on 0 and 'A-F' otherwise.
   @return CRYPT_OK if successful
*/
int base16_encode(const unsigned char *in,  unsigned long  inlen,
                                 char *out, unsigned long *outlen,
                        unsigned int   options)
{
   unsigned long i, x;
   const char *alphabet;
   const char *alphabets[2] = {
      "0123456789abcdef",
      "0123456789ABCDEF",
   };

   LTC_ARGCHK(in     != NULL);
   LTC_ARGCHK(out    != NULL);
   LTC_ARGCHK(outlen != NULL);

   /* check the sizes */
   x = inlen * 2 + 1;

   if (x < inlen) return CRYPT_OVERFLOW;

   if (*outlen < x) {
      *outlen = x;
      return CRYPT_BUFFER_OVERFLOW;
   }
   x--;
   *outlen = x; /* returning the length without terminating NUL */

   if (options == 0) {
      alphabet = alphabets[0];
   } else {
      alphabet = alphabets[1];
   }

   for (i = x; i > 0; i -= 2) {
      out[i-2] = alphabet[(in[(i-1)/2] >> 4) & 0x0f];
      out[i-1] = alphabet[in[(i-1)/2] & 0x0f];
   }

   out[x] = '\0';

   return CRYPT_OK;
}

#endif
