1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.kerberos.shared.crypto.encryption;
21  
22  
23  import java.security.GeneralSecurityException;
24  import java.security.spec.AlgorithmParameterSpec;
25  import java.util.Arrays;
26  
27  import javax.crypto.Cipher;
28  import javax.crypto.SecretKey;
29  import javax.crypto.spec.IvParameterSpec;
30  import javax.crypto.spec.SecretKeySpec;
31  
32  import junit.framework.TestCase;
33  
34  
35  /**
36   * Tests the use of AES for Kerberos, using test vectors from RFC 3962,
37   * "Advanced Encryption Standard (AES) Encryption for Kerberos 5."
38   *
39   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
40   * @version $Rev$, $Date$
41   */
42  public class AesEncryptionTest extends TestCase
43  {
44      private byte[] keyBytes =
45          { ( byte ) 0x63, ( byte ) 0x68, ( byte ) 0x69, ( byte ) 0x63, ( byte ) 0x6b, ( byte ) 0x65, ( byte ) 0x6e,
46              ( byte ) 0x20, ( byte ) 0x74, ( byte ) 0x65, ( byte ) 0x72, ( byte ) 0x69, ( byte ) 0x79, ( byte ) 0x61,
47              ( byte ) 0x6b, ( byte ) 0x69 };
48  
49      private SecretKey key = new SecretKeySpec( keyBytes, "AES" );
50  
51      private byte[] iv =
52          { ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
53              ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
54              ( byte ) 0x00, ( byte ) 0x00, };
55  
56      private AlgorithmParameterSpec paramSpec = new IvParameterSpec( iv );
57  
58  
59      /**
60       * Tests the first test vector from RFC 3962,
61       * "Advanced Encryption Standard (AES) Encryption for Kerberos 5."
62       */
63      public void testFirstAesVector()
64      {
65          if ( !VendorHelper.isCtsSupported() )
66          {
67              return;
68          }
69  
70          byte[] input =
71              { ( byte ) 0x49, ( byte ) 0x20, ( byte ) 0x77, ( byte ) 0x6f, ( byte ) 0x75, ( byte ) 0x6c, ( byte ) 0x64,
72                  ( byte ) 0x20, ( byte ) 0x6c, ( byte ) 0x69, ( byte ) 0x6b, ( byte ) 0x65, ( byte ) 0x20,
73                  ( byte ) 0x74, ( byte ) 0x68, ( byte ) 0x65, ( byte ) 0x20 };
74  
75          byte[] output =
76              { ( byte ) 0xc6, ( byte ) 0x35, ( byte ) 0x35, ( byte ) 0x68, ( byte ) 0xf2, ( byte ) 0xbf, ( byte ) 0x8c,
77                  ( byte ) 0xb4, ( byte ) 0xd8, ( byte ) 0xa5, ( byte ) 0x80, ( byte ) 0x36, ( byte ) 0x2d,
78                  ( byte ) 0xa7, ( byte ) 0xff, ( byte ) 0x7f, ( byte ) 0x97 };
79  
80          byte[] result = aesCipher( key, input );
81  
82          assertEquals( "Length", input.length, result.length );
83          assertTrue( Arrays.equals( output, result ) );
84      }
85  
86  
87      /**
88       * Tests the last test vector from RFC 3962,
89       * "Advanced Encryption Standard (AES) Encryption for Kerberos 5."
90       */
91      public void testLastAesVector()
92      {
93          if ( !VendorHelper.isCtsSupported() )
94          {
95              return;
96          }
97  
98          byte[] input =
99              { ( byte ) 0x49, ( byte ) 0x20, ( byte ) 0x77, ( byte ) 0x6f, ( byte ) 0x75, ( byte ) 0x6c, ( byte ) 0x64,
100                 ( byte ) 0x20, ( byte ) 0x6c, ( byte ) 0x69, ( byte ) 0x6b, ( byte ) 0x65, ( byte ) 0x20,
101                 ( byte ) 0x74, ( byte ) 0x68, ( byte ) 0x65, ( byte ) 0x20, ( byte ) 0x47, ( byte ) 0x65,
102                 ( byte ) 0x6e, ( byte ) 0x65, ( byte ) 0x72, ( byte ) 0x61, ( byte ) 0x6c, ( byte ) 0x20,
103                 ( byte ) 0x47, ( byte ) 0x61, ( byte ) 0x75, ( byte ) 0x27, ( byte ) 0x73, ( byte ) 0x20,
104                 ( byte ) 0x43, ( byte ) 0x68, ( byte ) 0x69, ( byte ) 0x63, ( byte ) 0x6b, ( byte ) 0x65,
105                 ( byte ) 0x6e, ( byte ) 0x2c, ( byte ) 0x20, ( byte ) 0x70, ( byte ) 0x6c, ( byte ) 0x65,
106                 ( byte ) 0x61, ( byte ) 0x73, ( byte ) 0x65, ( byte ) 0x2c, ( byte ) 0x20, ( byte ) 0x61,
107                 ( byte ) 0x6e, ( byte ) 0x64, ( byte ) 0x20, ( byte ) 0x77, ( byte ) 0x6f, ( byte ) 0x6e,
108                 ( byte ) 0x74, ( byte ) 0x6f, ( byte ) 0x6e, ( byte ) 0x20, ( byte ) 0x73, ( byte ) 0x6f,
109                 ( byte ) 0x75, ( byte ) 0x70, ( byte ) 0x2e };
110 
111         byte[] output =
112             { ( byte ) 0x97, ( byte ) 0x68, ( byte ) 0x72, ( byte ) 0x68, ( byte ) 0xd6, ( byte ) 0xec, ( byte ) 0xcc,
113                 ( byte ) 0xc0, ( byte ) 0xc0, ( byte ) 0x7b, ( byte ) 0x25, ( byte ) 0xe2, ( byte ) 0x5e,
114                 ( byte ) 0xcf, ( byte ) 0xe5, ( byte ) 0x84, ( byte ) 0x39, ( byte ) 0x31, ( byte ) 0x25,
115                 ( byte ) 0x23, ( byte ) 0xa7, ( byte ) 0x86, ( byte ) 0x62, ( byte ) 0xd5, ( byte ) 0xbe,
116                 ( byte ) 0x7f, ( byte ) 0xcb, ( byte ) 0xcc, ( byte ) 0x98, ( byte ) 0xeb, ( byte ) 0xf5,
117                 ( byte ) 0xa8, ( byte ) 0x48, ( byte ) 0x07, ( byte ) 0xef, ( byte ) 0xe8, ( byte ) 0x36,
118                 ( byte ) 0xee, ( byte ) 0x89, ( byte ) 0xa5, ( byte ) 0x26, ( byte ) 0x73, ( byte ) 0x0d,
119                 ( byte ) 0xbc, ( byte ) 0x2f, ( byte ) 0x7b, ( byte ) 0xc8, ( byte ) 0x40, ( byte ) 0x9d,
120                 ( byte ) 0xad, ( byte ) 0x8b, ( byte ) 0xbb, ( byte ) 0x96, ( byte ) 0xc4, ( byte ) 0xcd,
121                 ( byte ) 0xc0, ( byte ) 0x3b, ( byte ) 0xc1, ( byte ) 0x03, ( byte ) 0xe1, ( byte ) 0xa1,
122                 ( byte ) 0x94, ( byte ) 0xbb, ( byte ) 0xd8 };
123 
124         byte[] result = aesCipher( key, input );
125 
126         assertEquals( "Length", input.length, result.length );
127         assertTrue( Arrays.equals( output, result ) );
128     }
129 
130 
131     private byte[] aesCipher( SecretKey key, byte[] input )
132     {
133         try
134         {
135             Cipher ecipher = Cipher.getInstance( "AES/CTS/NoPadding" );
136             ecipher.init( Cipher.ENCRYPT_MODE, key, paramSpec );
137             return ecipher.doFinal( input );
138         }
139         catch ( GeneralSecurityException gse )
140         {
141             return new byte[]
142                 { 0x00 };
143         }
144     }
145 }