-
Notifications
You must be signed in to change notification settings - Fork 493
Expand file tree
/
Copy pathpadding_pad.c
More file actions
151 lines (130 loc) · 3.55 KB
/
Copy pathpadding_pad.c
File metadata and controls
151 lines (130 loc) · 3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#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 s_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;
}
LTC_FALLTHROUGH; /* FALLTHROUGH */
case LTC_PAD_PKCS7:
case LTC_PAD_ONE_AND_ZERO:
case LTC_PAD_ZERO_ALWAYS:
case LTC_PAD_SSH:
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 l, n;
enum padding_type type;
int err;
unsigned char diff, pad;
LTC_ARGCHK(data != NULL);
LTC_ARGCHK(padded_length != NULL);
l = length;
if ((err = s_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;
}
if (l - length > 255) return CRYPT_INVALID_ARG;
diff = (unsigned char)(l - length);
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-1u, NULL) != diff-1u) {
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_SSH:
pad = 0x1;
for (n = length; n < l; ++n) {
data[n] = pad++;
}
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