summary refs log tree commit diff
path: root/Crypto/src/crypto/StreamBlockCipher.cs
blob: ef2a8b68aa27bf5e39a35ab48d16d21c2348ae41 (plain) (blame)
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
using System;

using Org.BouncyCastle.Crypto.Parameters;

namespace Org.BouncyCastle.Crypto
{
	/**
	 * a wrapper for block ciphers with a single byte block size, so that they
	 * can be treated like stream ciphers.
	 */
	public class StreamBlockCipher
		: IStreamCipher
	{
		private readonly IBlockCipher cipher;
		private readonly byte[] oneByte = new byte[1];

		/**
		 * basic constructor.
		 *
		 * @param cipher the block cipher to be wrapped.
		 * @exception ArgumentException if the cipher has a block size other than
		 * one.
		 */
		public StreamBlockCipher(
			IBlockCipher cipher)
		{
			if (cipher == null)
				throw new ArgumentNullException("cipher");
			if (cipher.GetBlockSize() != 1)
				throw new ArgumentException("block cipher block size != 1.", "cipher");

			this.cipher = cipher;
		}

		/**
		 * initialise the underlying cipher.
		 *
		 * @param forEncryption true if we are setting up for encryption, false otherwise.
		 * @param param the necessary parameters for the underlying cipher to be initialised.
		 */
		public void Init(
			bool				forEncryption,
			ICipherParameters	parameters)
		{
			cipher.Init(forEncryption, parameters);
		}

		/**
		* return the name of the algorithm we are wrapping.
		*
		* @return the name of the algorithm we are wrapping.
		*/
		public string AlgorithmName
		{
			get { return cipher.AlgorithmName; }
		}

		/**
		* encrypt/decrypt a single byte returning the result.
		*
		* @param in the byte to be processed.
		* @return the result of processing the input byte.
		*/
		public byte ReturnByte(
			byte input)
		{
			oneByte[0] = input;

			cipher.ProcessBlock(oneByte, 0, oneByte, 0);

			return oneByte[0];
		}

		/**
		* process a block of bytes from in putting the result into out.
		*
		* @param in the input byte array.
		* @param inOff the offset into the in array where the data to be processed starts.
		* @param len the number of bytes to be processed.
		* @param out the output buffer the processed bytes go into.
		* @param outOff the offset into the output byte array the processed data stars at.
		* @exception DataLengthException if the output buffer is too small.
		*/
		public void ProcessBytes(
			byte[]	input,
			int		inOff,
			int		length,
			byte[]	output,
			int		outOff)
		{
			if (outOff + length > output.Length)
				throw new DataLengthException("output buffer too small in ProcessBytes()");

			for (int i = 0; i != length; i++)
			{
				cipher.ProcessBlock(input, inOff + i, output, outOff + i);
			}
		}

		/**
		* reset the underlying cipher. This leaves it in the same state
		* it was at after the last init (if there was one).
		*/
		public void Reset()
		{
			cipher.Reset();
		}
	}
}