// SPDX-License-Identifier: BSD-2-Clause
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
 *
 * LibTomCrypt is a library that provides various cryptographic
 * algorithms in a highly modular and flexible manner.
 *
 * The library is free for all purposes without any express
 * guarantee it works.
 */
#include "tomcrypt_private.h"

#ifdef LTC_PADDING

/**
   Determine the to-be-padded length.

   @param length     [in/out] The size of the data before/after padding
   @param mode       Mask of (LTC_PAD_xxx | block_length)
   @return CRYPT_OK on success
*/
static int _padding_padded_length(unsigned long *length, unsigned long mode)
{
   enum padding_type padding;
   unsigned char pad, block_length, r, t;

   LTC_ARGCHK(length != NULL);

   block_length = mode & 0xff;
   padding = mode & LTC_PAD_MASK;
   r = *length % block_length;

   switch (padding) {
      case LTC_PAD_ZERO:
         if (r == 0) {
            t = 0;
            break;
         }
         /* FALLTHROUGH */
      case LTC_PAD_PKCS7:
      case LTC_PAD_ONE_AND_ZERO:
      case LTC_PAD_ZERO_ALWAYS:
         t = 1;
         break;
#ifdef LTC_RNG_GET_BYTES
      case LTC_PAD_ISO_10126:
         do {
            if (rng_get_bytes(&t, sizeof(t), NULL) != sizeof(t)) {
               return CRYPT_ERROR_READPRNG;
            }
            t %= (256 / block_length);
         } while (t == 0);
         break;
#endif
      case LTC_PAD_ANSI_X923:
         if (block_length != 16) {
            return CRYPT_INVALID_ARG;
         }
         t = 1;
         break;
      default:
         return CRYPT_INVALID_ARG;
   }

   pad = (t * block_length) - r;

   if ((pad == 0) && (padding != LTC_PAD_ZERO)) {
      pad = block_length;
   }

   *length += pad;

   return CRYPT_OK;
}

/**
   Add padding to data.

      This pads your data.

   @param data          The data to depad
   @param length        The size of the data before padding
   @param padded_length [in/out] The size of the data available/after padding
   @param mode          One of the LTC_PAD_xx flags
   @return CRYPT_OK on success
*/
int padding_pad(unsigned char *data, unsigned long length, unsigned long* padded_length, unsigned long mode)
{
   unsigned long diff, l;
   enum padding_type type;
   int err;

   LTC_ARGCHK(data          != NULL);
   LTC_ARGCHK(padded_length != NULL);

   l = length;
   if ((err = _padding_padded_length(&l, mode)) != CRYPT_OK) {
      return err;
   }

   type = mode & LTC_PAD_MASK;

   if (*padded_length < l) {
#ifdef LTC_RNG_GET_BYTES
      if (type != LTC_PAD_ISO_10126) {
         *padded_length = l;
      } else {
         *padded_length = length + 256;
      }
#else
      *padded_length = l;
#endif
      return CRYPT_BUFFER_OVERFLOW;
   }

   diff = l - length;
   if (diff > 255) return CRYPT_INVALID_ARG;

   switch (type) {
      case LTC_PAD_PKCS7:
         XMEMSET(&data[length], diff, diff);
         break;
#ifdef LTC_RNG_GET_BYTES
      case LTC_PAD_ISO_10126:
         if (rng_get_bytes(&data[length], diff-1, NULL) != diff-1) {
            return CRYPT_ERROR_READPRNG;
         }
         data[l-1] =  diff;
         break;
#endif
      case LTC_PAD_ANSI_X923:
         XMEMSET(&data[length], 0, diff-1);
         data[l-1] =  diff;
         break;
      case LTC_PAD_ONE_AND_ZERO:
         XMEMSET(&data[length + 1], 0, diff);
         data[length] =  0x80;
         break;
      case LTC_PAD_ZERO:
      case LTC_PAD_ZERO_ALWAYS:
         XMEMSET(&data[length], 0, diff);
         break;
      default:
         return CRYPT_INVALID_ARG;
   }
   *padded_length = l;

   return CRYPT_OK;
}

#endif

/* ref:         $Format:%D$ */
/* git commit:  $Format:%H$ */
/* commit time: $Format:%ai$ */
