Main Page | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

eap_archie_crypto.hxx

00001 /* BEGIN_COPYRIGHT                                                        */
00002 /*                                                                        */
00003 /* Open Diameter: Open-source software for the Diameter and               */
00004 /*                Diameter related protocols                              */
00005 /*                                                                        */
00006 /* Copyright (C) 2002-2004 Open Diameter Project                          */
00007 /*                                                                        */
00008 /* This library is free software; you can redistribute it and/or modify   */
00009 /* it under the terms of the GNU Lesser General Public License as         */
00010 /* published by the Free Software Foundation; either version 2.1 of the   */
00011 /* License, or (at your option) any later version.                        */
00012 /*                                                                        */
00013 /* This library is distributed in the hope that it will be useful,        */
00014 /* but WITHOUT ANY WARRANTY; without even the implied warranty of         */
00015 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      */
00016 /* Lesser General Public License for more details.                        */
00017 /*                                                                        */
00018 /* You should have received a copy of the GNU Lesser General Public       */
00019 /* License along with this library; if not, write to the Free Software    */
00020 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307    */
00021 /* USA.                                                                   */
00022 /*                                                                        */
00023 /* In addition, when you copy and redistribute some or the entire part of */
00024 /* the source code of this software with or without modification, you     */
00025 /* MUST include this copyright notice in each copy.                       */
00026 /*                                                                        */
00027 /* If you make any changes that are appeared to be useful, please send    */
00028 /* sources that include the changed part to                               */
00029 /* diameter-developers@lists.sourceforge.net so that we can reflect your  */
00030 /* changes to one unified version of this software.                       */
00031 /*                                                                        */
00032 /* END_COPYRIGHT                                                          */
00033 // $Id: eap_archie_crypto.hxx,v 1.4 2004/06/17 21:13:36 yohba Exp $
00034 
00035 // EAP-Archie cryptographic functions.
00036 // Written by Yoshihiro Ohba (yohba@tari.toshiba.com)
00037 
00038 #ifndef __EAP_ARCHIE_CRYPTO_HXX__
00039 #define __EAP_ARCHIE_CRYPTO_HXX__
00040 
00041 #include <openssl/aes.h>
00042 #include <string.h>
00043 
00044 /* From draft-jwalker-eap-archie-01.txt:
00045 
00046 3.1. AES-CBC-MAC-128 and AES-CBC-MAC-96
00047                                                                                
00048 This section reviews the definition of the AES-CBC-MAC.
00049                                                                                
00050 Let K denote an AES key, and let AES-Encrypt denote the AES encrypt
00051 primitive. The AES-CBC-MAC-128 of a string S is defined using the
00052 following steps:
00053                                                                                
00054 a. Let L denote the length of S in octets. Let L' = L + p, where p
00055    is the unique integer 0 <= p < 16 needed so that L' is a
00056    multiple of 16.
00057 b. Let n = L'/16, and partition S into substrings, such that
00058    S = S[1] S[2] ... S[n-1] S'[n], with S[1], S[2], ..., S[n-1]
00059    consisting of 16 octets each and S'[n] consisting of 16 octets
00060    if p is 0 and 16-p octets otherwise. Let S[n] = S'[n]0^p, where
00061    0^p denotes p octets of zero pad.
00062 c. Set IV to 16 zero octets.
00063 d. For i = 1 to n do
00064       IV = AES-Encrypt(K, S[i] XOR IV)
00065 e. Return IV.
00066                                                                                
00067 The EAP-Archie protocol uses a variant of AES-CBC-MAC-128 called
00068 AES-CBC-MAC-96. This variant differs from the AES-CBC-MAC-128
00069 described above in only step e, which it replaces by:
00070                                                                                
00071 e'. Return the first 12 octets of IV.
00072                                                                                
00073 Note that any padding added in step b is used to compute the MAC value
00074 only, and is never sent as part of an EAP-Archie message.
00075  */
00076 
00078 class EapCryptoAES_CBC_MAC
00079 {
00080 public:
00081   enum MAC_LengthType {
00082     MAC_Length96,
00083     MAC_Length128
00084   };
00091   void operator()(std::string& in, std::string& out, 
00092                   std::string& sharedSecret, MAC_LengthType lengthType)
00093   {
00094     // Number of 16-octet blocks.
00095     int L = (int)in.size();
00096     int n = (L - 1) / 16 + 1; 
00097 
00098     AES_KEY key;
00099     AES_set_encrypt_key((const unsigned char*)sharedSecret.data(), 128, &key);
00100 
00101     std::string tmp(16*n, '\0');
00102     tmp.replace(0, in.size(), in);
00103 
00104     unsigned char IV[16]; 
00105     ACE_OS::memset(IV, 0, sizeof IV);
00106 
00107     for (int i=0; i<n; i++)
00108       {
00109             const char* S = tmp.data() + 16*i;
00110             // Calculate XOR.
00111             for (int j=0; j<16; j++) { IV[j] ^= S[j]; }
00112         AES_encrypt((const unsigned char*)IV, IV, &key);
00113       }
00114     out.assign((char*)IV,  (lengthType == MAC_Length96) ? 12 : 16);
00115   }
00116 };
00117 
00118 /* From draft-jwalker-eap-archie-01.txt:
00119 
00120 3.2. The Archie-PRF
00121                                                                                
00122 This section defines the Archie-PRF function.
00123                                                                                
00124 Let K denote a key, and let Length denote the number of octets
00125 desired. The Archie-PRF of a string S is defined by the following
00126 steps:
00127                                                                                
00128 a. Output is initialized to the null string.
00129 b. For i = 1 to (Length+15)/16 do
00130       Output = Output | AES-CBC-MAC-128(K, i | S | Length)
00131 c. Return first Length octets of Output
00132                                                                                
00133 In step b, the loop index i and the Length are encoded as 32-bit
00134 big-Endian unsigned integers.
00135                                                                                
00136  */
00137 
00139 class EapCryptoArchiePRF
00140 {
00141 public:
00142   void operator()(std::string& in, std::string& out, std::string& sharedSecret,
00143                   ACE_UINT32 length)
00144   {
00145     out.assign("");
00146     std::string tmp;
00147     ACE_UINT32 lengthNBO = ntohl(length); // representation of length
00148                                           // in networkbyte order.
00149     for (ACE_UINT32 i=1; i <= (length+15)/16; i++)
00150       {
00151         ACE_UINT32 iNBO = ntohl(i); // representation of i in network
00152                                     // byte order.
00153         tmp.assign((char*)&iNBO, sizeof iNBO);
00154         tmp.append(in);
00155         tmp.append((char*)&lengthNBO, sizeof lengthNBO);
00156         EapCryptoAES_CBC_MAC mac;
00157         mac(tmp, tmp, sharedSecret, EapCryptoAES_CBC_MAC::MAC_Length128);
00158         out.append(tmp);
00159       }
00160     out.resize(length);
00161   }
00162 };
00163 
00164 #endif

Generated on Fri Jun 25 19:16:16 2004 for EAP State Machine by doxygen 1.3.5