1 module dcrypt.blockcipher.padding.x923; 2 3 import dcrypt.blockcipher.padding.padding; 4 import dcrypt.exceptions; 5 import std.exception: enforce; 6 7 8 static assert(isBlockCipherPadding!X923Pad, "X923Pad violates isBlockCipherPadding."); 9 10 /// 11 /// A ANSI X.923 block cipher padding implementation. 12 /// This code does not support random padding anymore, 13 /// because the author thinks its more susceptible to padding oracle attacks than deterministic zero padding. 14 /// 15 @safe 16 public struct X923Pad { 17 18 public enum name = "X.923"; 19 20 21 public { 22 23 /** 24 * pad with zeros or random bytes if SecureRandom is specified in constructor. 25 * Params: block = the block to pad 26 * len = the number of data bytes in this block. has to be smaller than block.length. 27 */ 28 void addPadding(ubyte[] block, in uint len) nothrow 29 in{ 30 assert(len < block.length, "len has to be smaller than block size"); 31 assert(block.length < 256, "block to long. can't pad blocks with length > 255"); 32 } 33 body { 34 35 if(len < block.length) { 36 // zero pad 37 block[len..$] = 0; 38 // set last byte to length of padding 39 block[$-1] = cast(ubyte)(block.length-len); 40 } 41 } 42 43 /** 44 * Returns: the number of padding bytes appended to this block 45 * Throws: InvalidCipherTextException if the padding is corrupted 46 */ 47 uint padCount(in ubyte[] block) pure 48 body { 49 ubyte len = block[$-1]; 50 51 enforce(len <= block.length, new InvalidCipherTextException("pad block corrupted")); 52 53 // check if the padding is really made out of zeros 54 foreach(b; block[$-len..$-1]) { 55 enforce(b == 0, new InvalidCipherTextException("pad block corrupted")); 56 } 57 58 return len; 59 } 60 } 61 } 62 63 /// Test X923 padding scheme. 64 unittest { 65 X923Pad padding; 66 ubyte[] block = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]; 67 padding.addPadding(block, 15); 68 assert(block == [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,1], "X923Padding failed"); 69 assert(padding.padCount(block) == 1, "X923Padding failed"); 70 padding.addPadding(block, 7); 71 assert(block == [0,1,2,3,4,5,6,0,0,0,0,0,0,0,0,9], "X923Padding failed"); 72 assert(padding.padCount(block) == 9, "X923Padding failed"); 73 padding.addPadding(block, 0); 74 assert(block == [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16], "X923Padding failed"); 75 assert(padding.padCount(block) == 16, "X923Padding failed"); 76 }