| | | 1 | | using System; |
| | | 2 | | |
| | | 3 | | using Renci.SshNet.Security.Org.BouncyCastle.Utilities; |
| | | 4 | | |
| | | 5 | | namespace Renci.SshNet.Security.Org.BouncyCastle.Crypto.Digests |
| | | 6 | | { |
| | | 7 | | internal abstract class GeneralDigest |
| | | 8 | | : IDigest, IMemoable |
| | | 9 | | { |
| | | 10 | | private const int BYTE_LENGTH = 64; |
| | | 11 | | |
| | | 12 | | private byte[] xBuf; |
| | | 13 | | private int xBufOff; |
| | | 14 | | |
| | | 15 | | private long byteCount; |
| | | 16 | | |
| | 10 | 17 | | internal GeneralDigest() |
| | 10 | 18 | | { |
| | 10 | 19 | | xBuf = new byte[4]; |
| | 10 | 20 | | } |
| | | 21 | | |
| | 0 | 22 | | internal GeneralDigest(GeneralDigest t) |
| | 0 | 23 | | { |
| | 0 | 24 | | xBuf = new byte[t.xBuf.Length]; |
| | 0 | 25 | | CopyIn(t); |
| | 0 | 26 | | } |
| | | 27 | | |
| | | 28 | | protected void CopyIn(GeneralDigest t) |
| | 0 | 29 | | { |
| | 0 | 30 | | Array.Copy(t.xBuf, 0, xBuf, 0, t.xBuf.Length); |
| | | 31 | | |
| | 0 | 32 | | xBufOff = t.xBufOff; |
| | 0 | 33 | | byteCount = t.byteCount; |
| | 0 | 34 | | } |
| | | 35 | | |
| | | 36 | | public void Update(byte input) |
| | 152 | 37 | | { |
| | 152 | 38 | | xBuf[xBufOff++] = input; |
| | | 39 | | |
| | 152 | 40 | | if (xBufOff == xBuf.Length) |
| | 38 | 41 | | { |
| | 38 | 42 | | ProcessWord(xBuf, 0); |
| | 38 | 43 | | xBufOff = 0; |
| | 38 | 44 | | } |
| | | 45 | | |
| | 152 | 46 | | byteCount++; |
| | 152 | 47 | | } |
| | | 48 | | |
| | | 49 | | public void BlockUpdate( |
| | | 50 | | byte[] input, |
| | | 51 | | int inOff, |
| | | 52 | | int length) |
| | 94 | 53 | | { |
| | 94 | 54 | | length = System.Math.Max(0, length); |
| | | 55 | | |
| | | 56 | | // |
| | | 57 | | // fill the current word |
| | | 58 | | // |
| | 94 | 59 | | int i = 0; |
| | 94 | 60 | | if (xBufOff != 0) |
| | 0 | 61 | | { |
| | 0 | 62 | | while (i < length) |
| | 0 | 63 | | { |
| | 0 | 64 | | xBuf[xBufOff++] = input[inOff + i++]; |
| | 0 | 65 | | if (xBufOff == 4) |
| | 0 | 66 | | { |
| | 0 | 67 | | ProcessWord(xBuf, 0); |
| | 0 | 68 | | xBufOff = 0; |
| | 0 | 69 | | break; |
| | | 70 | | } |
| | 0 | 71 | | } |
| | 0 | 72 | | } |
| | | 73 | | |
| | | 74 | | // |
| | | 75 | | // process whole words. |
| | | 76 | | // |
| | 94 | 77 | | int limit = ((length - i) & ~3) + i; |
| | 1262 | 78 | | for (; i < limit; i += 4) |
| | 584 | 79 | | { |
| | 584 | 80 | | ProcessWord(input, inOff + i); |
| | 584 | 81 | | } |
| | | 82 | | |
| | | 83 | | // |
| | | 84 | | // load in the remainder. |
| | | 85 | | // |
| | 94 | 86 | | while (i < length) |
| | 0 | 87 | | { |
| | 0 | 88 | | xBuf[xBufOff++] = input[inOff + i++]; |
| | 0 | 89 | | } |
| | | 90 | | |
| | 94 | 91 | | byteCount += length; |
| | 94 | 92 | | } |
| | | 93 | | |
| | | 94 | | public void Finish() |
| | 38 | 95 | | { |
| | 38 | 96 | | long bitLength = (byteCount << 3); |
| | | 97 | | |
| | | 98 | | // |
| | | 99 | | // add the pad bytes. |
| | | 100 | | // |
| | 38 | 101 | | Update((byte)128); |
| | | 102 | | |
| | 266 | 103 | | while (xBufOff != 0) Update((byte)0); |
| | 38 | 104 | | ProcessLength(bitLength); |
| | 38 | 105 | | ProcessBlock(); |
| | 38 | 106 | | } |
| | | 107 | | |
| | | 108 | | public virtual void Reset() |
| | 38 | 109 | | { |
| | 38 | 110 | | byteCount = 0; |
| | 38 | 111 | | xBufOff = 0; |
| | 38 | 112 | | Array.Clear(xBuf, 0, xBuf.Length); |
| | 38 | 113 | | } |
| | | 114 | | |
| | | 115 | | public int GetByteLength() |
| | 0 | 116 | | { |
| | 0 | 117 | | return BYTE_LENGTH; |
| | 0 | 118 | | } |
| | | 119 | | |
| | | 120 | | internal abstract void ProcessWord(byte[] input, int inOff); |
| | | 121 | | internal abstract void ProcessLength(long bitLength); |
| | | 122 | | internal abstract void ProcessBlock(); |
| | | 123 | | public abstract string AlgorithmName { get; } |
| | | 124 | | public abstract int GetDigestSize(); |
| | | 125 | | public abstract int DoFinal(byte[] output, int outOff); |
| | | 126 | | public abstract IMemoable Copy(); |
| | | 127 | | public abstract void Reset(IMemoable t); |
| | | 128 | | } |
| | | 129 | | } |