crypt/key.cc

Go to the documentation of this file.
00001 // $Id: key.cc,v 1.5 2008-02-07 23:39:10 rafi Exp $
00002 //
00003 // YAPET -- Yet Another Password Encryption Tool
00004 // Copyright (C) 2008  Rafael Ostertag
00005 //
00006 // This program is free software: you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation, either version 3 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // This program is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License
00017 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 //
00019 
00020 #include "key.h"
00021 
00022 #ifdef HAVE_STRING_H
00023 # include <string.h>
00024 #endif
00025 
00026 using namespace YAPET;
00027 
00032 void
00033 Key::cleanup() {
00034     memset(key, 0, KEYLENGTH);
00035     memset(IVec, 0, IVECLENGTH);
00036 }
00037 
00045 Key::Key(const char* password) throw(YAPETException) {
00046     // Sentinel variable to check the size of the key
00047     uint8_t eff_keylength;
00048         
00049     //
00050     // First run (sha1)
00051     //
00052     const EVP_MD* md = EVP_sha1();
00053     if (md == NULL)
00054     throw YAPETException("Run 1: Unable to initialize the EVP_MD structure");
00055 
00056     EVP_MD_CTX mdctx;
00057     EVP_MD_CTX_init(&mdctx);
00058 
00059     int retval = EVP_DigestInit_ex(&mdctx, md, NULL);
00060     if (retval == 0) {
00061     EVP_MD_CTX_cleanup(&mdctx);
00062     throw YAPETException("Run 1: Unable to initialize the digest");
00063     }
00064 
00065     retval = EVP_DigestUpdate(&mdctx, password, strlen(password));
00066     if (retval == 0) {
00067     EVP_MD_CTX_cleanup(&mdctx);
00068     throw YAPETException("Run 1: Unable to update the digest");
00069     }
00070 
00071     unsigned int tmplen;
00072     retval = EVP_DigestFinal_ex(&mdctx, key, &tmplen);
00073     if (retval == 0) {
00074     EVP_MD_CTX_cleanup(&mdctx);
00075     cleanup();
00076     throw YAPETException("Run 1: Unable to finalize the digest");
00077     }
00078 
00079     if (tmplen != SHA1_LEN) {
00080     EVP_MD_CTX_cleanup(&mdctx);
00081     cleanup();
00082     throw YAPETException("Run 1: Digest does not have expected length");
00083     }
00084 
00085     eff_keylength = tmplen;
00086     EVP_MD_CTX_cleanup(&mdctx);
00087 
00088     //
00089     // Second run (md5)
00090     //
00091     md = EVP_md5();
00092     if (md == NULL) {
00093     cleanup();
00094     throw YAPETException("Run 2: Unable to initialize the EVP_MD structure");
00095     }
00096 
00097     EVP_MD_CTX_init(&mdctx);
00098     retval = EVP_DigestInit_ex(&mdctx, md, NULL);
00099     if (retval == 0) {
00100     EVP_MD_CTX_cleanup(&mdctx);
00101     cleanup();
00102     throw YAPETException("Run 2: Unable to initialize the digest");
00103     }
00104 
00105     retval = EVP_DigestUpdate(&mdctx, key, SHA1_LEN);
00106     if (retval == 0) {
00107     EVP_MD_CTX_cleanup(&mdctx);
00108     cleanup();
00109     throw YAPETException("Run 2: Unable to update the digest");
00110     }
00111 
00112     retval = EVP_DigestFinal_ex(&mdctx, key + SHA1_LEN, &tmplen);
00113     if (retval == 0) {
00114     EVP_MD_CTX_cleanup(&mdctx);
00115     cleanup();
00116     throw YAPETException("Run 2: Unable to finalize the digest");
00117     }
00118 
00119     if (tmplen != MD5_LEN) {
00120     EVP_MD_CTX_cleanup(&mdctx);
00121     cleanup();
00122     throw YAPETException("Run 2: Digest does not have expected length");
00123     }
00124 
00125     eff_keylength += tmplen;
00126     EVP_MD_CTX_cleanup(&mdctx);
00127 
00128     //
00129     // Third run (ripemd160)
00130     //
00131     md = EVP_ripemd160();
00132     if (md == NULL) {
00133     cleanup();
00134     throw YAPETException("Run 3: Unable to initialize the EVP_MD structure");
00135     }
00136 
00137     EVP_MD_CTX_init(&mdctx);
00138     retval = EVP_DigestInit_ex(&mdctx, md, NULL);
00139     if (retval == 0) {
00140     EVP_MD_CTX_cleanup(&mdctx);
00141     cleanup();
00142     throw YAPETException("Run 3: Unable to initialize the digest");
00143     }
00144 
00145     retval = EVP_DigestUpdate(&mdctx, key, SHA1_LEN + MD5_LEN);
00146     if (retval == 0) {
00147     EVP_MD_CTX_cleanup(&mdctx);
00148     cleanup();
00149     throw YAPETException("Run 3: Unable to update the digest");
00150     }
00151 
00152     retval = EVP_DigestFinal_ex(&mdctx, key + SHA1_LEN + MD5_LEN, &tmplen);
00153     if (retval == 0) {
00154     EVP_MD_CTX_cleanup(&mdctx);
00155     cleanup();
00156     throw YAPETException("Run 3: Unable to finalize the digest");
00157     }
00158 
00159     if (tmplen != RIPEMD160_LEN) {
00160     EVP_MD_CTX_cleanup(&mdctx);
00161     cleanup();
00162     throw YAPETException("Run 3: Digest does not have expected length");
00163     }
00164 
00165     eff_keylength += tmplen;
00166     EVP_MD_CTX_cleanup(&mdctx);
00167     
00168     if (eff_keylength != KEYLENGTH) {
00169     cleanup();
00170     char tmp[100];
00171     snprintf(tmp,
00172          100,
00173          "Effective key length of %d does not match expected key length %d",
00174          eff_keylength,
00175          KEYLENGTH);
00176     throw YAPETException(tmp);
00177     }
00178 
00179     //
00180     // The initialization vector
00181     //
00182     uint8_t ivec_hash_buf[MD5_LEN];
00183     md = EVP_md5();
00184     if (md == NULL) {
00185     cleanup();
00186     throw YAPETException("IVec: Unable to initialize the EVP_MD structure");
00187     }
00188 
00189     EVP_MD_CTX_init(&mdctx);
00190     retval = EVP_DigestInit_ex(&mdctx, md, NULL);
00191     if (retval == 0) {
00192     EVP_MD_CTX_cleanup(&mdctx);
00193     cleanup();
00194     throw YAPETException("IVec: Unable to initialize the digest");
00195     }
00196 
00197     retval = EVP_DigestUpdate(&mdctx, key, SHA1_LEN + MD5_LEN + RIPEMD160_LEN);
00198     if (retval == 0) {
00199     EVP_MD_CTX_cleanup(&mdctx);
00200     cleanup();
00201     throw YAPETException("IVec: Unable to update the digest");
00202     }
00203 
00204     retval = EVP_DigestFinal_ex(&mdctx, ivec_hash_buf, &tmplen);
00205     if (retval == 0) {
00206     EVP_MD_CTX_cleanup(&mdctx);
00207     cleanup();
00208     throw YAPETException("IVec: Unable to finalize the digest");
00209     }
00210 
00211     if (tmplen != MD5_LEN) {
00212     EVP_MD_CTX_cleanup(&mdctx);
00213     cleanup();
00214     throw YAPETException("IVec: Digest does not have expected length");
00215     }
00216 
00217     EVP_MD_CTX_cleanup(&mdctx);
00218 
00219     memcpy(IVec, ivec_hash_buf, IVECLENGTH);
00220     memset(ivec_hash_buf, 0, MD5_LEN);
00221 }
00222 
00223 Key::Key(const Key& k) {
00224     memcpy(key, k.key, KEYLENGTH);
00225     memcpy(IVec, k.IVec, IVECLENGTH);
00226 }
00227 
00228 Key::~Key() {
00229     cleanup();
00230 }
00231 
00232 const Key&
00233 Key::operator=(const Key& k) {
00234     if (this == &k) return *this;
00235 
00236     cleanup();
00237 
00238     memcpy(key, k.key, KEYLENGTH);
00239     memcpy(IVec, k.IVec, IVECLENGTH);
00240 
00241     return *this;
00242 }
00243 
00254 bool
00255 Key::operator==(const Key& k) const {
00256     if (k.size() != size()) return false;
00257     if (k.ivec_size() != ivec_size()) return false;
00258 
00259     int retval = memcmp(k.key, key, size());
00260     if (retval != 0)
00261     return false;
00262 
00263     retval = memcmp(k.IVec, IVec, ivec_size());
00264     if (retval != 0)
00265     return false;
00266 
00267     return true;
00268 }

Generated on Wed Feb 27 16:15:41 2008 for YAPET by  doxygen 1.5.4