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 #include "tomcrypt_private.h"
11 
12 #ifdef LTC_PADDING
13 
14 /**
15    Remove padding from your data
16 
17       This depads your data.
18 
19    @param data     The data to depad
20    @param length   [in/out] The size of the data before/after (removing padding)
21    @param mode     One of the LTC_PAD_xx flags
22    @return CRYPT_OK on success
23 */
padding_depad(const unsigned char * data,unsigned long * length,unsigned long mode)24 int padding_depad(const unsigned char *data, unsigned long *length, unsigned long mode)
25 {
26    unsigned long padded_length, unpadded_length, n;
27    unsigned char pad;
28    enum padding_type type;
29 
30    LTC_ARGCHK(data   != NULL);
31    LTC_ARGCHK(length != NULL);
32 
33    padded_length = *length;
34 
35    type = mode & LTC_PAD_MASK;
36 
37    if (type < LTC_PAD_ONE_AND_ZERO) {
38       pad = data[padded_length - 1];
39 
40       if (pad > padded_length || pad == 0) return CRYPT_INVALID_ARG;
41 
42       unpadded_length = padded_length - pad;
43    } else {
44       /* init pad to calm old compilers */
45       pad = 0x0;
46       unpadded_length = padded_length;
47    }
48 
49    switch (type) {
50       case LTC_PAD_ANSI_X923:
51          pad = 0x0;
52          /* FALLTHROUGH */
53       case LTC_PAD_PKCS7:
54          for (n = unpadded_length; n < padded_length - 1; ++n) {
55             if (data[n] != pad) return CRYPT_INVALID_PACKET;
56          }
57          break;
58 #ifdef LTC_RNG_GET_BYTES
59       case LTC_PAD_ISO_10126:
60          /* nop */
61          break;
62 #endif
63       case LTC_PAD_ONE_AND_ZERO:
64          while (unpadded_length > 0 && data[unpadded_length - 1] != 0x80) {
65             if (data[unpadded_length - 1] != 0x0) return CRYPT_INVALID_PACKET;
66             unpadded_length--;
67          }
68          if (unpadded_length == 0) return CRYPT_INVALID_PACKET;
69          unpadded_length--;
70          if (data[unpadded_length] != 0x80) return CRYPT_INVALID_PACKET;
71          break;
72       case LTC_PAD_ZERO:
73       case LTC_PAD_ZERO_ALWAYS:
74          while (unpadded_length > 0 && data[unpadded_length - 1] == 0x0) {
75             unpadded_length--;
76          }
77          if (type == LTC_PAD_ZERO_ALWAYS) {
78             if (unpadded_length == padded_length) return CRYPT_INVALID_PACKET;
79             if (data[unpadded_length] != 0x0) return CRYPT_INVALID_PACKET;
80          }
81          break;
82       default:
83          return CRYPT_INVALID_ARG;
84    }
85 
86    *length = unpadded_length;
87 
88    return CRYPT_OK;
89 }
90 
91 #endif
92 
93 /* ref:         $Format:%D$ */
94 /* git commit:  $Format:%H$ */
95 /* commit time: $Format:%ai$ */
96