1   /* $RCSfile: DESCoreEde3KeyBlockCipher.java,v $
2    * $Revision: 1.5 $
3    * $Date: 2001/11/02 09:11:00 $
4    * $Author: uwe $
5    * $State: Exp $
6    *
7    * Created on August 7, 2001 4:52 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   * DESCoreEde3KeyBlockCipher Class.
39   *
40   * @author  <a href=mailto:uwe@cscc.de>Uwe G&uuml;nther</a>
41   * @version $Revision: 1.5 $
42   */
43  class DESCoreEde3KeyBlockCipher extends DESCoreBlockCipher {
44      
45      /** 
46       * DES block cipher algorithm object with key1. Will be
47       * used for encryption in ede mode for stage 1,
48       * respectively for decryption also in stage 1.
49       */    
50      private DESCore1KeyBlockCipher cipherWithKey1;
51      
52      /** 
53       * DES block cipher algorithm object with key2. Will be
54       * used for encryption in ede mode for stage 2,
55       * respectively for decryption also in stage 2.
56       */    
57      private DESCore1KeyBlockCipher cipherWithKey2;
58  
59      /** 
60       * DES block cipher algorithm object with key3. Will be
61       * used for encryption in ede mode for stage 3,
62       * respectively for decryption also in stage 3.
63       */    
64      private DESCore1KeyBlockCipher cipherWithKey3;    
65      
66      /** 
67       * Don't create a DESCoreEde3KeyBlockCipher object with default constructor.
68       */
69      private DESCoreEde3KeyBlockCipher() {}
70  
71      /** 
72       * Creates a DESCoreEde3KeyBlockCipher algorithm instance with 
73       * this byte[24] key, starting at offset. 
74       *
75       * @param key the key that is used for this algorithm object.
76       * @throws IllegalBlockSizeException will be thrown, if the
77       *          deliverd byte array is less than 24 byte.
78       */        
79      public DESCoreEde3KeyBlockCipher(byte[] key) 
80              throws IllegalBlockSizeException {
81                  
82          this.cipherWithKey1 =new DESCore1KeyBlockCipher(key, 0);
83          this.cipherWithKey2 =new DESCore1KeyBlockCipher(key, 8);
84          this.cipherWithKey3 =new DESCore1KeyBlockCipher(key, 16);        
85      }
86  
87      /** 
88       * Creates a DESCoreEde3KeyBlockCipher algorithm instance with 
89       * this byte[offset+24] key, starting at offset. 
90       *
91       * @param key the key that is used for this algorithm object.
92       * @param offset to start at.
93       * @throws IllegalBlockSizeException will be thrown, if the
94       *          deliverd byte array is less than offset+24 byte.
95       */        
96      public DESCoreEde3KeyBlockCipher(byte[] key, int offset) 
97              throws IllegalBlockSizeException  {
98                  
99          this.cipherWithKey1 =new DESCore1KeyBlockCipher(key, offset+0);
100         this.cipherWithKey2 =new DESCore1KeyBlockCipher(key, offset+8);
101         this.cipherWithKey3 =new DESCore1KeyBlockCipher(key, offset+16);        
102     }
103     
104     /** 
105      * Returns a string representation of the object. 
106      *
107      * @return  a string representation of the object.
108      */
109     public String toString() {
110         
111         return "cipherWithKey1: [" + this.cipherWithKey1.toString() + "] [" +
112                "cipherWithKey2: [" + this.cipherWithKey2.toString() + "] [" +
113                "cipherWithKey3: [" + this.cipherWithKey3.toString() + "]"; 
114     }
115     
116     /** 
117      * Returns the algorithm specific key size in bits. If you subclass 
118      * these abstract class, you have to implement these method.
119      *
120      * @return the algorithm specific key size in bits.
121      */
122     public int getKeyBitSize() {
123         
124         //168
125         return this.cipherWithKey1.getKeyBitSize() + 
126                this.cipherWithKey2.getKeyBitSize() +
127                this.cipherWithKey3.getKeyBitSize() ;
128     }            
129     
130     /** 
131      * Returns the algorithm specific key size in bytes. If you subclass 
132      * these abstract class, you have to implement these method.
133      *
134      * @return the algorithm specific key size in bytes.
135      */
136     public int getKeyByteSize() {
137 
138         //24
139         return this.cipherWithKey1.getKeyByteSize() +
140                this.cipherWithKey2.getKeyByteSize() +
141                this.cipherWithKey3.getKeyByteSize() ;
142     }
143          
144     /** 
145      * The DES encryption operation.
146      *
147      * If (input.length-inputOffset > 8) we use only the first 8 bytes 
148      * for the block.
149      *
150      * @param input the 64 bit data block that will be encrypted.
151      * @param inputOffset the offset in input where the input starts.
152      * @param output the buffer for the result.
153      * @param outputOffset the offset in output where the result is stored.
154      * @throws IllegalBlockSizeException will be thrown, if the
155      *          deliverd byte array has a length lesser than 8.
156      * @throws ShortBufferException will be thrown, if the
157      *          ouput buffer byte array has a length lesser than 8.
158      * @return the number of bytes stored in output.
159      */    
160     public int encrypt(byte[] input,  int inputOffset, 
161                        byte[] output, int outputOffset) 
162             throws IllegalBlockSizeException, ShortBufferException {
163                 
164         this.cipherWithKey1.encrypt(input, inputOffset, output, outputOffset);
165         this.cipherWithKey2.decrypt(output, outputOffset, output, outputOffset);
166         return this.cipherWithKey1.encrypt(output, outputOffset, output, outputOffset);                
167     }
168     
169     /**
170      * The DES decryption operation.
171      *
172      * If (input.length-inputOffset > 8) we use only the first 8 bytes for the block.
173      *
174      * @param input the 64 bit data block that will be decrypted.
175      * @param inputOffset the offset in input where the input starts.
176      * @param output the buffer for the result.
177      * @param outputOffset the offset in output where the result is stored.
178      * @throws IllegalBlockSizeException will be thrown, if the
179      *          deliverd byte array has a length lesser than 8.
180      * @throws ShortBufferException will be thrown, if the
181      *          ouput buffer byte array has a length lesser than 8.
182      * @return the number of bytes stored in output.
183      */    
184     public int decrypt(byte[] input,  int inputOffset, 
185                        byte[] output, int outputOffset) 
186             throws IllegalBlockSizeException, ShortBufferException {
187                 
188         this.cipherWithKey1.decrypt(input, inputOffset, output, outputOffset);
189         this.cipherWithKey2.encrypt(output, outputOffset, output, outputOffset);
190         return this.cipherWithKey1.decrypt(output, outputOffset, output, outputOffset);        
191     }
192 }
193