1   /* $RCSfile: BlockCipher.java,v $
2    * $Revision: 1.10 $
3    * $Date: 2002/01/04 12:10:47 $
4    * $Author: uwe $
5    * $State: Exp $
6    *
7    * Created on August 3, 2001 3:49 PM
8    *
9    * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
10   *
11   * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
12   * ServiceProvider is a library, written in JavaTM, that should be 
13   * used in HBCI banking applications (clients and may be servers),
14   * to do cryptographic operations.
15   *
16   * The jhbci library is free software; you can redistribute it and/or
17   * modify it under the terms of the GNU Lesser General Public
18   * License as published by the Free Software Foundation; either
19   * version 2.1 of the License, or (at your option) any later version.
20   *
21   * The jhbci library is distributed in the hope that it will be useful,
22   * but WITHOUT ANY WARRANTY; without even the implied warranty of
23   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24   * Lesser General Public License for more details.
25   *
26   * You should have received a copy of the GNU Lesser General Public
27   * License along with this library; if not, write to the Free Software
28   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29   *
30   */
31  
32  package de.cscc.crypto.provider;
33  
34  import javax.crypto.IllegalBlockSizeException;
35  import javax.crypto.ShortBufferException;
36  
37  /** 
38   * BlockCipher Interface.
39   *
40   * @author  <a href=mailto:uwe@cscc.de>Uwe G&uuml;nther</a>
41   * @version $Revision: 1.10 $
42   */ 
43  abstract class BlockCipher {
44      
45      /** 
46       * Return the algorithm specific block size in bytes. These block
47       * size will be processed if one encrypt or decrypt method runs.
48       * If you subclass these abstract class, you have to implement these
49       * method.
50       *
51       * @return the algorithm specific block size in bytes.
52       */
53      public abstract int getBlockSize();
54          
55      /** 
56       * Return the algorithm specific key size in bits. If you subclass 
57       * these abstract class, you have to implement these method.
58       *
59       * @return the algorithm specific key size in bits.
60       */
61      public abstract int getKeyBitSize();    
62      
63      /** 
64       * Return the algorithm specific key size in bytes. If you subclass 
65       * these abstract class, you have to implement these method.
66       *
67       * @return the algorithm specific key size in bytes.
68       */
69      public abstract int getKeyByteSize();        
70     
71      /** 
72       * The encryption operation.
73       *
74       * Use it to encrypt whole getBlockSize() long plaintext blocks camouflaged
75       * as byte[getBlockSize()] blocks. This operation handels only byte arrays
76       * with a length of getBlockSize() byte or greater. Has the input byte 
77       * array a length lesser than 8 an
78       * {@link javax.crypto.IllegalBlockSizeException} will be thrown.
79       *
80       * If (input.length > getBlockSize()) we us only the first getBlockSize()
81       * bytes for the input block.
82       *
83       * <PRE>
84       * See the following example code:
85       * public class Main{
86       *      public static void main(String[] args){
87       *
88       *          byte[] plain = {(byte)0x4e, (byte)0x6f,
89       *                          (byte)0x77, (byte)0x20,
90       *                          (byte)0x69, (byte)0x73,
91       *                          (byte)0x20, (byte)0x74
92       *                         };
93       *
94       *          byte[] myKey = {(byte)0x01, (byte)0x23,
95       *                          (byte)0x45, (byte)0x67,
96       *                          (byte)0x89, (byte)0xab,
97       *                          (byte)0xcd, (byte)0xef
98       *                        };
99       *
100      *          try{
101      *              BlockCipher myBlockCipher =
102      *                  new DESCore1KeyBlockCipher(myKey);
103      *          } catch(IllegalBlockSizeException e){
104      *              e.printStackTrace();
105      *              System.exit(1);
106      *          }
107      *
108      *          try{
109      *              byte[] cipher = myBlockCipher.encrypt(plain);
110      *          } catch(IllegalBlockSizeException e){
111      *              e.printStackTrace();
112      *              System.exit(1);
113      *          }
114      *
115      *          //do something with the cipher[8] array...
116      *
117      *          return;
118      *      }
119      * }
120      * </PRE>
121      * @param input the getBlockSize() long data block that will be encrypted.
122      * @throws IllegalBlockSizeException will be thrown, if the
123      *          deliverd byte array has a length lesser than getBlockSize().
124      * @return a byte[getBlockSize()] array with the ciphertext.
125      */         
126     public byte[] encrypt(byte[] input) throws IllegalBlockSizeException {
127         
128         //Throws IllegalBlockSizeException and IllegalStateException.        
129         return encrypt(input, 0);    
130     }
131 
132 
133     /** 
134      * The encryption operation.
135      *
136      * If (input.length-inputOffset > getBlockSize()) we us only the first 
137      * getBlockSize() bytes from the block.
138      *
139      * @param input the getBlockSize() data block that will be encrypted.
140      * @param inputOffset the offset in block where the input starts.
141      * @throws IllegalBlockSizeException will be thrown, if the
142      *         deliverd byte array has a length lesser than getBlockSize().
143      * @return a byte[getBlockSize()] array with the ciphertext.
144      */    
145     public byte[] encrypt(byte[] input, int inputOffset) 
146             throws IllegalBlockSizeException {
147                 
148         byte[] returnValue = new byte[getBlockSize()];
149         
150         try{
151             encrypt(input, inputOffset, returnValue, 0);
152         } catch (ShortBufferException cannothappen) {            
153             //These exception won't be thrown because we deliver the 
154             //byte array with the right lenth (ever getBlockSize() bytes long).            
155             throw new Error("Can not happen.", cannothappen);
156         } 
157         
158         //Return the result as byte[getBlockSize()].        
159         return returnValue;    
160     }
161 
162      
163     /** 
164      * The abstract encryption operation. If you subclass these abstract class,
165      * you have to implement these method.
166      *
167      * If (input.length-inputOffset > getBlockSize()) we use only the first 
168      * getBlockSize() bytes from the block.
169      *
170      * @param input the getBlockSize() long data block that will be encrypted.
171      * @param inputOffset the offset in input where the input starts.
172      * @param output the buffer for the result.
173      * @param outputOffset the offset in output where the result is stored.
174      * @throws IllegalBlockSizeException will be thrown, if the
175      *          deliverd byte array has a length lesser than getBlockSize().
176      * @throws ShortBufferException will be thrown, if the
177      *          ouput buffer byte array has a length lesser than getBlockSize().
178      * @return the number of bytes stored in output.
179      */    
180     public abstract int encrypt(byte[] input,  int inputOffset, 
181             byte[] output, int outputOffset) 
182             throws IllegalBlockSizeException, ShortBufferException;    
183     
184     /** 
185      * The decryption operation.
186      *
187      * Use it to decrypt whole getBlockSize() long ciphertext blocks camouflaged
188      * as byte[getBlockSize()] blocks. This operation handles only byte arrays
189      * with a length of getBlockSize() bytes or greater. Has the input byte 
190      * array a length lesser than getBlockSize() an
191      * {@link javax.crypto.IllegalBlockSizeException} will be thrown.
192      *
193      * If (input.length > getBlockSize()) we use only the first getBlockSize() 
194      * bytes for the input block.
195      *
196      * <PRE>
197      * See the following example code:
198      *
199      * import javax.crypto.IllegalBlockSizeException;
200      *
201      * public class Main{
202      *      public static void main(String[] args){
203      *
204      *          byte[] cipher = {(byte)0x3f, (byte)0xa4,
205      *                          (byte)0x0e, (byte)0x8a,
206      *                          (byte)0x98, (byte)0x4d,
207      *                          (byte)0x48, (byte)0x15
208      *                        };
209      *
210      *          byte[] myKey = {(byte)0x01, (byte)0x23,
211      *                          (byte)0x45, (byte)0x67,
212      *                          (byte)0x89, (byte)0xab,
213      *                          (byte)0xcd, (byte)0xef
214      *                        };
215      *
216      *          try{
217      *              BlockCipher myBlockCipher =
218      *                  new DESCore1KeyBlockCipher(myKey);
219      *          } catch(IllegalBlockSizeException e){
220      *              e.printStackTrace();
221      *              System.exit(1);
222      *          }
223      *
224      *          try{
225      *              byte[] plain = myBlockCipher.decrypt(cipher);
226      *          } catch(IllegalBlockSizeException e){
227      *              e.printStackTrace();
228      *              System.exit(1);
229      *          }
230      *
231      *          //do something with the plain[8] array...
232      *
233      *          return;
234      *      }
235      * }
236      * </PRE>
237      * @param input the getBlockSize() long data block that will be decrypted.
238      * @throws IllegalBlockSizeException will be thrown, if the
239      *          deliverd byte array has a length lesser than getBlockSize().
240      * @return a byte[getBlockSize()] array with the plaintext.
241      */    
242     public byte[] decrypt(byte[] input) throws IllegalBlockSizeException {
243         
244         //Throws IllegalBlockSizeException. 
245         return decrypt(input, 0);    
246     }
247     
248     
249     /** 
250      * The decryption operation.
251      *
252      * If (input.length-inputOffset > getBlockSize()) we use only the first 
253      * getBlockSize() bytes for the block.
254      *
255      * @param input the getBlockSize() long data block that will be decrypted.
256      * @param inputOffset the offset in block where the input starts.
257      * @throws IllegalBlockSizeException will be thrown, if the
258      *         deliverd byte array has a length lesser than getBlockSize().
259      * @return a byte[getBlockSize()] array with the ciphertext.
260      */    
261     public byte[] decrypt(byte[] input, int inputOffset) 
262             throws IllegalBlockSizeException {
263                 
264         byte[] returnValue = new byte[getBlockSize()];
265         
266         try{
267             decrypt(input, inputOffset, returnValue, 0);
268         } catch (ShortBufferException cannothappen) {
269             throw new Error("Can not happen.", cannothappen);
270         }
271         
272         //Return the result as byte[getBlockSize()].        
273         return returnValue;
274     }
275 
276      
277     /** 
278      * The abstract decryption operation. If you subclass these abstract class,
279      * you have to implement these method.
280      *
281      * If (input.length-inputOffset > getBlockSize()) we use only the first 
282      * getBlockSize() bytes for the block.
283      *
284      * @param input the getBlockSize() long data block that will be decrypted.
285      * @param inputOffset the offset in input where the input starts.
286      * @param output the buffer for the result.
287      * @param outputOffset the offset in output where the result is stored.
288      * @throws IllegalBlockSizeException will be thrown, if the
289      *          deliverd byte array has a length lesser than getBlockSize().
290      * @throws ShortBufferException will be thrown, if the
291      *          ouput buffer byte array has a length lesser than getBlockSize().
292      * @return the number of bytes stored in output.
293      */    
294     public abstract int decrypt(byte[] input,  int inputOffset, 
295             byte[] output, int outputOffset) 
296             throws IllegalBlockSizeException, ShortBufferException;
297 
298 }
299