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