1 /*******************************************************************************
2 3 Miscellaneous cryptographic padding functions
4 5 Copyright:
6 Copyright (c) 2009-2016 dunnhumby Germany GmbH.
7 All rights reserved.
8 9 License:
10 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
11 Alternatively, this file may be distributed under the terms of the Tango
12 3-Clause BSD License (see LICENSE_BSD.txt for details).
13 14 *******************************************************************************/15 16 moduleocean.util.cipher.misc.Padding;
17 18 19 importocean.meta.types.Qualifiers;
20 importocean.core.Verify;
21 22 version (unittest)
23 {
24 importocean.core.Test;
25 }
26 27 /*******************************************************************************
28 29 PKCS#7 padding.
30 31 Pads the given byte buffer to the given length. The value of the padding
32 byte is the same as the number of bytes added to the buffer, example:
33 34 A 3-byte buffer with the contents [0xAB, 0xCD, 0xEF] is padded to length 8.
35 The buffer will now contain [0xAB, 0xCD, 0xEF, 0x05, 0x05, 0x05, 0x05, 0x05]
36 37 PKCS#7 padding is only defined for cases where the number of bytes to be
38 padded is less than 256.
39 40 Params:
41 buffer = A reference to the buffer to pad
42 pad_len = The length to pad the buffer to
43 44 Returns:
45 The padded buffer
46 47 *******************************************************************************/48 49 ubyte[] padPKCS7 ( refubyte[] buffer, size_tpad_len )
50 {
51 verify(pad_len >= buffer.length);
52 verify(pad_len - buffer.length <= ubyte.max);
53 54 assumeSafeAppend(buffer);
55 56 ubytepad_byte = cast(ubyte)(pad_len - buffer.length);
57 58 size_tstart = buffer.length;
59 buffer.length = pad_len;
60 buffer[start .. $] = pad_byte;
61 62 returnbuffer;
63 }
64 65 unittest66 {
67 ubyte[] buf0;
68 test!("==")(padPKCS7(buf0, 0), cast(ubyte[])null);
69 test!("==")(padPKCS7(buf0, 1), cast(ubyte[])[1]);
70 71 autobuf = cast(ubyte[])"YELLOW SUBMARINE".dup;
72 autopadded = padPKCS7(buf, 20);
73 autoexpected = cast(ubyte[])"YELLOW SUBMARINE".dup ~ cast(ubyte[])[4, 4, 4, 4];
74 test!("==")(padded, expected);
75 }
76 77 /*******************************************************************************
78 79 PKCS#5 padding.
80 81 Similar to PKCS#7 padding, except PKCS#5 padding is only defined for ciphers
82 that use a block size of 8 bytes. Hence, the given buffer will be padded to
83 a length of 8 bytes.
84 85 Params:
86 buffer = A reference to the buffer to pad
87 88 Returns:
89 The padded buffer
90 91 *******************************************************************************/92 93 ubyte[] padPKCS5 ( refubyte[] buffer )
94 {
95 verify(buffer.length <= 8);
96 97 staticimmutablePKCS5_BLOCK_SIZE = 8;
98 returnpadPKCS7(buffer, PKCS5_BLOCK_SIZE);
99 }
100 101 unittest102 {
103 ubyte[] buf0;
104 test!("==")(padPKCS5(buf0), cast(ubyte[])[8, 8, 8, 8, 8, 8, 8, 8]);
105 106 autobuf = cast(ubyte[])[0xAB, 0xCD, 0xEF];
107 autopadded = padPKCS5(buf);
108 autoexpected = cast(ubyte[])[0xAB, 0xCD, 0xEF, 5, 5, 5, 5, 5];
109 test!("==")(padded, expected);
110 }