/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Yokogawa Electric Corporation,
* YDC Corporation, IPA (Information-technology Promotion Agency, Japan).
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* conditions and disclaimer are agreed and accepted by the user:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the names of the copyrighters, the name of the project which
* is related to this software (hereinafter referred to as "project") nor
* the names of the contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. No merchantable use may be permitted without prior written
* notification to the copyrighters. However, using this software for the
* purpose of testing or evaluating any products including merchantable
* products may be permitted without any notification to the copyrighters.
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHTERS, THE PROJECT AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING
* BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHTERS, THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT,STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $TAHI: v6eval/lib/Pz/MfAlgorithm.cc,v 1.29 2005/05/09 09:35:24 akisada Exp $
*/
#include "MfAlgorithm.h"
#include "PAlgorithm.h"
#include "PvOctets.h"
#include "CmMain.h"
#include "sslconfig.h"
#include <string.h>
#include "debug.h"
//----------------------------------------------------------------------
OCTBUF* MfESPPad::Padding_Octets(uint32_t len) const {
return padding_->substr(0,len);}
OCTBUF* MfESPPad::defaultOctets(uint32_t len) {
MfESPPad* m=defaultPadding();
return m!=0?m->Padding_Octets(len):new PvOctets(len);}
OCTBUF *
MfESPPad::IKEdefaultOctets(uint32_t len)
{
MfESPPad *m = IKEdefaultPadding();
return(m? m->Padding_Octets(len): new PvOctets(len));
}
//----------------------------------------------------------------------
// NULL AUTHENTIFICATION
OCTSTR MfAuth::init(OCTSTR,const PObjectList&) const {return 0;}
void MfAuth::update(OCTSTR,const PObjectList&,const OCTBUF&) const {}
PvOctets* MfAuth::result(OCTSTR,const PObjectList&) const {return 0;}
uint32_t MfAuth::alignment(const PObjectList&) const {return alignUnit();}
//----------------------------------------------------------------------
// NULL CRYPT ALGORITHM
uint32_t MfCrypt::alignment(const PObjectList& args) const {
uint32_t n=alignTimes(args);
uint8_t u=alignUnit();
return n>1?n*u:u;}
bool MfCrypt::alignmentCheck(uint32_t l,const PObjectList& args) const {
uint8_t reqAlign=alignUnit();
if(l%reqAlign!=0) {
printf("log: length %d not match with required alignment %d on %s\n",
l,reqAlign,string());
return false;}
uint32_t funcAlign=alignment(args);
if(l%funcAlign!=0) {
printf("log: length %d not match with function alignment %d on %s\n",
l,funcAlign,string());}
return true;}
//----------------------------------------------------------------------
uint32_t MfCrypt::alignTimes(const PObjectList& args) const {
uint32_t n=1;
if(args.size()>0) {
bool ok=true;
n=args[0]->intValue(ok);
if(!ok) n=1;}
return n>1?n:1;}
uint32_t MfCryptKey::alignTimes(const PObjectList& args) const {
uint32_t n=1;
if(args.size()>2) {
bool ok=true;
n=args[2]->intValue(ok);
if(!ok) n=1;}
return n>1?n:1;}
//----------------------------------------------------------------------
const PObject* MfCrypt::key(const PObjectList&) const {
return 0;}
const PObject* MfCryptKey::key(const PObjectList& args) const {
return (args.size()>0)?args[0]:0;}
//----------------------------------------------------------------------
void MfCrypt::encrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject*,OCTSTR) const {
memcpy(os,is,l);}
void MfCrypt::decrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject*,OCTSTR) const {
memcpy(os,is,l);}
//----------------------------------------------------------------------
OCTBUF* MfCrypt::encryptOctets(const OCTBUF& text,const PObjectList& a,OCTBUF* ivec) const {
if(DBGFLAGS('E')) {printf("===text\n"); text.dump(); printf("\n");}
//--------------------------------------------------------------
// length check
uint32_t lenc=text.length();
//--------------------------------------------------------------
// initial vector
// if no ivec specified in function, it's depend on malloc
// how can i return random value?
// should i make it error?
OCTSTR ivp=0;
if(a.size()>1) {
bool ok=true;
ivp=(OCTSTR)a[1]->octetsValue(ok);}
uint32_t ivlen=ivecLength();
if(ivec!=0) {ivec->set(ivlen,ivp);}
PvOctets ivwork(ivlen,ivp,true); // IV field changes
PvOctets* enc=new PvOctets(ivlen+lenc);
OCTSTR os=enc->buffer();
OCTSTR is=(OCTSTR)text.string();
const PObject* k=key(a);
OCTSTR wp=ivwork.buffer();
memcpy(os,wp,ivlen); os+=ivlen; // initial vector
if(!alignmentCheck(lenc,a)) {
MfCrypt::encrypt(os,is,lenc,k,wp);}
else {
encrypt(os,is,lenc,k,wp);}
if(DBGFLAGS('E')) {printf("===encrypt\n"); enc->dump(); printf("\n");}
return enc;}
OCTBUF* MfCrypt::decryptOctets(const OCTBUF& cipher,const PObjectList& a,
OCTBUF*& ivec) const {
if(DBGFLAGS('D')) {printf("===cipher\n"); cipher.dump(); printf("\n");}
//--------------------------------------------------------------
// length check: use super class decrypt
uint32_t lcipher=cipher.length();
uint32_t ivlen=ivecLength();
uint32_t ldec=lcipher-ivlen;
//--------------------------------------------------------------
// initial vector
OCTSTR cp=(OCTSTR)cipher.string();
if(ivlen>0) {
if(ivec==0) {ivec=new PvOctets(0);}
ivec->set(ivlen,cp);}
PvOctets ivwork(ivlen,cp,true); // IV field changes
PvOctets* dec=new PvOctets(ldec);
OCTSTR os=dec->buffer();
OCTSTR is=cp+ivlen;
const PObject* k=key(a);
OCTSTR wp=ivwork.buffer();
if(!alignmentCheck(ldec,a)) {
MfCrypt::decrypt(os,is,ldec,k,wp);}
else {
decrypt(os,is,ldec,k,wp);}
if(DBGFLAGS('D')) {printf("===decrypt\n"); dec->dump(); printf("\n");}
return dec;}
#include <openssl/des.h>
//----------------------------------------------------------------------
// DESCBC CRYPT ALGORITHM
void MfDESCBC::scheduleKeys(const PObject* key,des_key_schedule& schd) const {
bool ok=true;
COCTSTR keys=key->octetsValue(ok);
des_key_sched((DES_CBLOCK_IN)keys,schd);}
void MfDESCBC::encrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject* key,OCTSTR iv) const {
des_key_schedule schd;
scheduleKeys(key,schd);
des_cbc_encrypt(is,os,l,schd,(DES_CBLOCK_IO)iv,DES_ENCRYPT);}
void MfDESCBC::decrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject* key,OCTSTR iv) const {
des_key_schedule schd;
scheduleKeys(key,schd);
des_cbc_encrypt(is,os,l,schd,(DES_CBLOCK_IO)iv,DES_DECRYPT);}
#include <openssl/blowfish.h>
//----------------------------------------------------------------------
// BLOWFISH CRYPT ALGORITHM
void MfBLOWFISH::scheduleKeys(const PObject* key,BF_KEY& schd) const {
bool ok=true;
COCTSTR keys=key->octetsValue(ok);
BF_set_key(&schd,key->length(),(OCTSTR)keys);}
void MfBLOWFISH::encrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject* key,OCTSTR iv) const {
BF_KEY schd;
scheduleKeys(key,schd);
BF_cbc_encrypt(is,os,l,&schd,iv,DES_ENCRYPT);}
void MfBLOWFISH::decrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject* key,OCTSTR iv) const {
BF_KEY schd;
scheduleKeys(key,schd);
BF_cbc_encrypt(is,os,l,&schd,iv,DES_DECRYPT);}
#include <openssl/rc5.h>
//----------------------------------------------------------------------
// RC5 CRYPT ALGORITHM
void MfRC5::scheduleKeys(const PObject* key,RC5_32_KEY& schd) const {
bool ok=true;
COCTSTR keys=key->octetsValue(ok);
RC5_32_set_key(&schd,key->length(),(OCTSTR)keys,RC5_16_ROUNDS);}
void MfRC5::encrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject* key,OCTSTR iv) const {
RC5_32_KEY schd;
scheduleKeys(key,schd);
RC5_32_cbc_encrypt(is,os,l,&schd,iv,DES_ENCRYPT);}
void MfRC5::decrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject* key,OCTSTR iv) const {
RC5_32_KEY schd;
scheduleKeys(key,schd);
RC5_32_cbc_encrypt(is,os,l,&schd,iv,DES_DECRYPT);}
#include <openssl/cast.h>
//----------------------------------------------------------------------
// CAST128 CRYPT ALGORITHM
void MfCAST128::scheduleKeys(const PObject* key,CAST_KEY& schd) const {
bool ok=true;
COCTSTR keys=key->octetsValue(ok);
CAST_set_key(&schd,key->length(),(OCTSTR)keys);}
void MfCAST128::encrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject* key,OCTSTR iv) const {
CAST_KEY schd;
scheduleKeys(key,schd);
CAST_cbc_encrypt(is,os,l,&schd,iv,DES_ENCRYPT);}
void MfCAST128::decrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject* key,OCTSTR iv) const {
CAST_KEY schd;
scheduleKeys(key,schd);
CAST_cbc_encrypt(is,os,l,&schd,iv,DES_DECRYPT);}
//----------------------------------------------------------------------
// DES3CBC CRYPT ALGORITHM
void MfDES3CBC::scheduleKeys(const PObject* key,des_key_schedule& schd0,
des_key_schedule& schd1,des_key_schedule& schd2) const{
bool ok=true;
COCTSTR keys=key->octetsValue(ok);
des_key_sched((DES_CBLOCK_IN)keys,schd0);
des_key_sched((DES_CBLOCK_IN)(keys+8),schd1);
des_key_sched((DES_CBLOCK_IN)(keys+16),schd2);}
void MfDES3CBC::encrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject* key,OCTSTR iv) const {
des_key_schedule schd0,schd1,schd2;
scheduleKeys(key,schd0,schd1,schd2);
des_ede3_cbc_encrypt(is,os,l,schd0,schd1,schd2,(DES_CBLOCK_IO)iv,DES_ENCRYPT);}
void MfDES3CBC::decrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject* key,OCTSTR iv) const {
des_key_schedule schd0,schd1,schd2;
scheduleKeys(key,schd0,schd1,schd2);
des_ede3_cbc_encrypt(is,os,l,schd0,schd1,schd2,(DES_CBLOCK_IO)iv,DES_DECRYPT);}
extern "C" {
#include <crypto/rijndael/rijndael.h>
}
//----------------------------------------------------------------------
// RIJNDAEL/AES CBC CRYPT ALGORITHM
void MfRIJNDAEL::encrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject* key,OCTSTR iv) const {
keyInstance k;
cipherInstance c;
bool ok=true;
COCTSTR keys=key->octetsValue(ok);
rijndael_makeKey(&k, DIR_ENCRYPT, key->length() << 3, (char *)keys);
rijndael_cipherInit(&c, MODE_CBC, (char *)iv);
rijndael_blockEncrypt(&c, &k, is, l << 3, os);}
void MfRIJNDAEL::decrypt(OCTSTR os,OCTSTR is,uint32_t l,const PObject* key,OCTSTR iv) const {
keyInstance k;
cipherInstance c;
bool ok=true;
COCTSTR keys=key->octetsValue(ok);
rijndael_makeKey(&k, DIR_DECRYPT, key->length() << 3, (char *)keys);
rijndael_cipherInit(&c, MODE_CBC, (char *)iv);
rijndael_blockDecrypt(&c, &k, is, l << 3, os);}
#include <openssl/hmac.h>
//----------------------------------------------------------------------
// HMAC AUTHENTIFICATION ALGORITHM
OCTSTR MfHMAC::init(OCTSTR cp,const PObjectList& a) const {
HMAC_CTX* ctx=cp!=0?(HMAC_CTX*)cp:new HMAC_CTX;
bool ok=true;
COCTSTR key=0;
uint32_t keylen=0;
if(a.size()>0) {
key=a[0]->octetsValue(ok);
keylen=a[0]->length();}
HMAC_Init(ctx,(OCTSTR)key,keylen,evp());
return (OCTSTR)ctx;}
void MfHMAC::update(OCTSTR cp,const PObjectList&,const OCTBUF& s) const {
HMAC_CTX* ctx=(HMAC_CTX*)cp;
HMAC_Update(ctx,(OCTSTR)s.string(),s.length());}
PvOctets* MfHMAC::result(OCTSTR cp,const PObjectList&) const {
HMAC_CTX* ctx=(HMAC_CTX*)cp;
uint32_t len=HMAC_MAX_MD_CBLOCK;
octet m[HMAC_MAX_MD_CBLOCK];
HMAC_Final(ctx,m,&len);
uint32_t icvlen=icvLength();
PvOctets* rc=new PvOctets(icvlen);
OCTSTR os=rc->buffer();
memcpy(os,m,icvlen);
HMAC_cleanup(ctx);
return rc;}
#include <crypto/sha2/sha2.h>
//----------------------------------------------------------------------
// EVP ALGORITHM
const EVP_MD* MfHMAC::evp() const {return 0;}
const EVP_MD* MfHMACMD5::evp() const {return EVP_md5();}
const EVP_MD* MfHMACSHA1::evp() const {return EVP_sha1();}
EVP_MD* MfHMACSHA2_256::evp() const {return EVP_sha2_256();}
EVP_MD* MfHMACSHA2_384::evp() const {return EVP_sha2_384();}
EVP_MD* MfHMACSHA2_512::evp() const {return EVP_sha2_512();}
//----------------------------------------------------------------------
bool MfESPPad::checkArgument(const PFunction&,const PObjectList&) const {
return true;}
bool MfAuth::checkArgument(const PFunction&,const PObjectList&) const {
return true;}
//----------------------------------------------------------------------
// xxx([key])
bool MfHMAC::checkArgument(const PFunction& o,const PObjectList& a) const {
bool ok=true;
bool rc=true;
uint32_t n=a.size();
CSTR name=o.metaString();
if(n!=0&&n!=1) {
o.error("E %s must have 0 or 1 argument, not %d",name,n);
return false;}
if(n==0) {return true;}
a[0]->octetsValue(ok);
if(!ok) {
o.error("E %s first argument has to be octets",name);
rc=false;}
return rc;}
//----------------------------------------------------------------------
// null([alignment])
bool MfCrypt::checkArgument(const PFunction& o,const PObjectList& a) const {
bool ok=true;
bool rc=true;
uint32_t n=a.size();
CSTR name=o.metaString();
if(n!=0&&n!=1) {
o.error("E %s must have 0 or 1 argument, not %d",name,n);
return false;}
if(n==0) {return true;}
a[0]->intValue(ok);
if(!ok) {
o.error("E %s first argument has to be int",name);
rc=false;}
return rc;}
//----------------------------------------------------------------------
// xxx(key[,ivec[,alignment]])
bool MfCryptKey::checkArgument(const PFunction& o,const PObjectList& a) const {
bool ok=true;
bool rc=true;
uint32_t n=a.size();
CSTR name=o.metaString();
if(n!=1&&n!=2&&n!=3) {
o.error("E %s mast have 1-3 arguments, not %d",name,n);
return false;}
a[0]->octetsValue(ok);
if(!ok) {
o.error("E %s first argument has to be octets",name);
rc=false;}
else {
uint32_t l=a[0]->length();
uint32_t kl=keyLength();
if(l!=kl) {
o.error("E %s key length has to be %d, not %d",name,kl,l);
rc=false;}}
if(n>1) {
a[1]->octetsValue(ok);
if(!ok) {
o.error("E %s second argument has to be octets",name);
rc=false;}
else {
uint32_t l=a[1]->length();
uint32_t il=ivecLength();
if(l!=il) {
o.error("E %s ivec length has to be %d, not %d",name,il,l);
rc=false;}}}
if(n==3) {
uint32_t t=a[2]->intValue(ok);
if(!ok) {
o.error("E %s third argument has to be int",name);
rc=false;}
uint32_t l=t*alignUnit();
if(l>256) {
o.error("E %s alignment %d is too big",name,t);
rc=false;}}
return rc;}
//----------------------------------------------------------------------
PObject* MfESPPad::tokenObject(int l,CSTR f) const {
return new PfESPPad(this,f,l);}
PObject* MfCrypt::tokenObject(int l,CSTR f) const {
return new PfCrypt(this,f,l);}
PObject* MfAuth::tokenObject(int l,CSTR f) const {
return new PfAuth(this,f,l);}
//----------------------------------------------------------------------
// CONSTRUCTOR/DESTRUCTOR
MfESPPad::MfESPPad(CSTR s,PvOctets* o):MvFunction(s),padding_(o) {}
MfESPPad::~MfESPPad() {}
MfCrypt::MfCrypt(CSTR s,uint8_t k,uint8_t i,uint8_t a):MvFunction(s),
keyLength_(k),ivecLength_(i),alignUnit_(a),dummy_(0) {}
MfCrypt::~MfCrypt() {}
MfESPPadAny::MfESPPadAny(CSTR s,PvOctets* o):MfESPPad(s,o) {}
MfESPPadAny::~MfESPPadAny() {}
MfCryptKey::MfCryptKey(CSTR s,uint8_t k,uint8_t i,uint8_t a):MfCrypt(s,k,i,a) {}
MfCryptKey::~MfCryptKey() {}
MfDESCBC::MfDESCBC(CSTR s,uint8_t k,uint8_t i,uint8_t a):MfCryptKey(s,k,i,a) {}
MfDESCBC::~MfDESCBC() {}
MfBLOWFISH::MfBLOWFISH(CSTR s,uint8_t k,uint8_t i,uint8_t a):MfCryptKey(s,k,i,a) {}
MfBLOWFISH::~MfBLOWFISH() {}
MfRC5::MfRC5(CSTR s,uint8_t k,uint8_t i,uint8_t a):MfCryptKey(s,k,i,a) {}
MfRC5::~MfRC5() {}
MfCAST128::MfCAST128(CSTR s,uint8_t k,uint8_t i,uint8_t a):MfCryptKey(s,k,i,a) {}
MfCAST128::~MfCAST128() {}
MfDES3CBC::MfDES3CBC(CSTR s,uint8_t k,uint8_t i,uint8_t a):MfCryptKey(s,k,i,a) {}
MfDES3CBC::~MfDES3CBC() {}
MfIKE_DESCBC::MfIKE_DESCBC(CSTR s, uint8_t k, uint8_t i, uint8_t a):
MfDESCBC(s, k, i, a) {}
MfIKE_DESCBC::~MfIKE_DESCBC() {}
MfIKE_DES3CBC::MfIKE_DES3CBC(CSTR s, uint8_t k, uint8_t i, uint8_t a):
MfDES3CBC(s, k, i, a) {}
MfIKE_DES3CBC::~MfIKE_DES3CBC() {}
MfDESCBC_2::MfDESCBC_2(CSTR s, uint8_t k, uint8_t i, uint8_t a):
MfIKE_DESCBC(s, k, i, a) {}
MfDESCBC_2::~MfDESCBC_2() {}
MfDES3CBC_2::MfDES3CBC_2(CSTR s, uint8_t k, uint8_t i, uint8_t a):
MfIKE_DES3CBC(s, k, i, a) {}
MfDES3CBC_2::~MfDES3CBC_2() {}
bool
MfIKE_DESCBC::checkArgument(const PFunction &o, const PObjectList &a) const
{
bool ok = true;
bool rc = true;
uint32_t n = a.size();
CSTR name = o.metaString();
if((n != 1) && (n != 2) && (n != 3)) {
o.error("E %s mast have 1-3 arguments, not %d", name, n);
return(false);
}
if(!a[0]->isOctets()) {
o.error("E %s first argument has to be octet stream", name);
rc = false;
}
if(n > 1) {
if(!a[0]->isOctets()) {
o.error("E %s second argument has to be octet stream",
name);
rc = false;
}
}
if(n == 3) {
uint32_t t = a[2]->intValue(ok);
if(!ok) {
o.error("E %s third argument has to be int", name);
rc = false;
}
uint32_t l = t * alignUnit();
if(l > 256) {
o.error("E %s alignment %d is too big", name, t);
rc = false;
}
}
return(rc);
}
bool
MfIKE_DES3CBC::checkArgument(const PFunction &o, const PObjectList &a) const
{
bool ok = true;
bool rc = true;
uint32_t n = a.size();
CSTR name = o.metaString();
if((n != 1) && (n != 2) && (n != 3)) {
o.error("E %s mast have 1-3 arguments, not %d", name, n);
return(false);
}
if(!a[0]->isOctets()) {
o.error("E %s first argument has to be octet stream", name);
rc = false;
}
if(n > 1) {
if(!a[0]->isOctets()) {
o.error("E %s second argument has to be octet stream",
name);
rc = false;
}
}
if(n == 3) {
uint32_t t = a[2]->intValue(ok);
if(!ok) {
o.error("E %s third argument has to be int", name);
rc = false;
}
uint32_t l = t * alignUnit();
if(l > 256) {
o.error("E %s alignment %d is too big", name, t);
rc = false;
}
}
return(rc);
}
OCTBUF *
MfIKE_DESCBC::encryptOctets(const OCTBUF &text,
const PObjectList &a, OCTBUF *ivec) const
{
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DESCBC", "plaintext",
text.string(), text.length());
#endif // ISAKMP_DBG
if(DBGFLAGS('E')) {
printf("===text\n");
text.dump();
printf("\n");
}
uint32_t lenc = text.length();
OCTSTR ivp = 0;
uint32_t ivlen = ivecLength();
PvOctets isakmp_ivec;
if(a.size() > 1) {
PObject *p1 = a[1];
if(p1->generateOctetsWith(isakmp_ivec, 0)) {
ivp = isakmp_ivec.buffer();
ivlen = isakmp_ivec.length();
}
}
if(ivec != 0) {
ivec->set(ivlen, ivp);
}
PvOctets ivwork(ivlen, ivp, true);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DESCBC", "ivec",
ivwork.buffer(), ivwork.length());
#endif // ISAKMP_DBG
PvOctets *enc = new PvOctets(lenc);
OCTSTR os = enc->buffer();
OCTSTR is = (OCTSTR)text.string();
PObject *p0 = a[0];
PvOctets isakmp_key;
p0->generateOctetsWith(isakmp_key, 0);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DESCBC", "key",
isakmp_key.buffer(), isakmp_key.length());
#endif // ISAKMP_DBG
const PObject *k = &isakmp_key;
OCTSTR wp = ivwork.buffer();
if(!alignmentCheck(lenc, a)) {
MfCrypt::encrypt(os, is, lenc, k, wp);
} else {
encrypt(os, is, lenc, k, wp);
}
if(DBGFLAGS('E')) {
printf("===encrypt\n");
enc->dump();
printf("\n");
}
return(enc);
}
OCTBUF *
MfIKE_DESCBC::decryptOctets(const OCTBUF &cipher,
const PObjectList &a, OCTBUF *&ivec) const
{
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DESCBC", "ciphertext",
cipher.string(), cipher.length());
#endif // ISAKMP_DBG
if(DBGFLAGS('D')) {
printf("===cipher\n");
cipher.dump();
printf("\n");
}
uint32_t lcipher = cipher.length();
uint32_t ivlen = ivecLength();
uint32_t ldec = lcipher;
OCTSTR cp = (OCTSTR)cipher.string();
OCTSTR ivp = 0;
PvOctets isakmp_ivec;
if(a.size() > 1) {
PObject *p1 = a[1];
if(p1->generateOctetsWith(isakmp_ivec, 0)) {
ivp = isakmp_ivec.buffer();
ivlen = isakmp_ivec.length();
}
}
if(ivlen > 0) {
if(!ivec) {
ivec = new PvOctets(0);
}
ivec->set(ivlen, ivp);
}
PvOctets ivwork(ivlen, ivp, true);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DESCBC", "ivec",
ivwork.buffer(), ivwork.length());
#endif // ISAKMP_DBG
PvOctets *dec = new PvOctets(ldec);
OCTSTR os = dec->buffer();
OCTSTR is = cp;
PObject *p0 = a[0];
PvOctets isakmp_key;
p0->generateOctetsWith(isakmp_key, 0);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DESCBC", "key",
isakmp_key.buffer(), isakmp_key.length());
#endif // ISAKMP_DBG
const PObject *k = &isakmp_key;
OCTSTR wp = ivwork.buffer();
if(!alignmentCheck(ldec,a)) {
MfCrypt::decrypt(os, is, ldec, k, wp);
} else {
decrypt(os, is, ldec, k, wp);
}
if(DBGFLAGS('D')) {
printf("===decrypt\n");
dec->dump();
printf("\n");
}
return(dec);
}
OCTBUF *
MfIKE_DES3CBC::encryptOctets(const OCTBUF &text,
const PObjectList &a, OCTBUF *ivec) const
{
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DES3CBC", "plaintext",
text.string(), text.length());
#endif // ISAKMP_DBG
if(DBGFLAGS('E')) {
printf("===text\n");
text.dump();
printf("\n");
}
uint32_t lenc = text.length();
OCTSTR ivp = 0;
uint32_t ivlen = ivecLength();
#ifdef ISAKMP_DBG
dbg("/tmp/isakmp_dbg.txt", "MfIKE_DES3CBC",
"a.size(): %d\n", a.size());
#endif // ISAKMP_DBG
PvOctets isakmp_ivec;
if(a.size() > 1) {
PObject *p1 = a[1];
if(p1->generateOctetsWith(isakmp_ivec, 0)) {
ivp = isakmp_ivec.buffer();
ivlen = isakmp_ivec.length();
}
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DES3CBC", "isakmp_ivec[right]",
isakmp_ivec.buffer(), isakmp_ivec.length());
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DES3CBC", "isakmp_ivec[left]",
ivp, ivlen);
#endif // ISAKMP_DBG
}
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DES3CBC", "isakmp_ivec[out:0]",
ivp, ivlen);
#endif // ISAKMP_DBG
if(ivec) {
ivec->set(ivlen, ivp);
}
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DES3CBC", "isakmp_ivec[out:1]",
ivp, ivlen);
#endif // ISAKMP_DBG
PvOctets ivwork(ivlen, ivp, true);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DES3CBC", "ivec",
ivwork.buffer(), ivwork.length());
#endif // ISAKMP_DBG
PvOctets *enc = new PvOctets(lenc);
OCTSTR os = enc->buffer();
OCTSTR is = (OCTSTR)text.string();
PObject *p0 = a[0];
PvOctets isakmp_key;
p0->generateOctetsWith(isakmp_key, 0);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DES3CBC", "key",
isakmp_key.buffer(), isakmp_key.length());
#endif // ISAKMP_DBG
const PObject *k = &isakmp_key;
OCTSTR wp = ivwork.buffer();
if(!alignmentCheck(lenc, a)) {
MfCrypt::encrypt(os, is, lenc, k, wp);
} else {
encrypt(os, is, lenc, k, wp);
}
if(DBGFLAGS('E')) {
printf("===encrypt\n");
enc->dump();
printf("\n");
}
return(enc);
}
OCTBUF *
MfIKE_DES3CBC::decryptOctets(const OCTBUF &cipher,
const PObjectList &a, OCTBUF *&ivec) const
{
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DES3CBC", "ciphertext",
cipher.string(), cipher.length());
#endif // ISAKMP_DBG
if(DBGFLAGS('D')) {
printf("===cipher\n");
cipher.dump();
printf("\n");
}
uint32_t lcipher = cipher.length();
uint32_t ivlen = ivecLength();
uint32_t ldec = lcipher;
OCTSTR cp = (OCTSTR)cipher.string();
OCTSTR ivp = 0;
PvOctets isakmp_ivec;
if(a.size() > 1) {
PObject *p1 = a[1];
if(p1->generateOctetsWith(isakmp_ivec, 0)) {
ivp = isakmp_ivec.buffer();
ivlen = isakmp_ivec.length();
}
}
if(ivlen > 0) {
if(!ivec) {
ivec = new PvOctets(0);
}
ivec->set(ivlen, ivp);
}
PvOctets ivwork(ivlen, ivp, true);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DES3CBC", "ivec",
ivwork.buffer(), ivwork.length());
#endif // ISAKMP_DBG
PvOctets *dec = new PvOctets(ldec);
OCTSTR os = dec->buffer();
OCTSTR is = cp;
PObject *p0 = a[0];
PvOctets isakmp_key;
p0->generateOctetsWith(isakmp_key, 0);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfIKE_DES3CBC", "key",
isakmp_key.buffer(), isakmp_key.length());
#endif // ISAKMP_DBG
const PObject *k = &isakmp_key;
OCTSTR wp = ivwork.buffer();
if(!alignmentCheck(ldec,a)) {
MfCrypt::decrypt(os, is, ldec, k, wp);
} else {
decrypt(os, is, ldec, k, wp);
}
if(DBGFLAGS('D')) {
printf("===decrypt\n");
dec->dump();
printf("\n");
}
return(dec);
}
OCTBUF *
MfDESCBC_2::encryptOctets(const OCTBUF &text,
const PObjectList &a, OCTBUF *ivec) const
{
if(DBGFLAGS('E')) {
printf("===text\n");
text.dump();
printf("\n");
}
uint32_t lenc = text.length();
OCTSTR ivp = 0;
PvOctets ipsec_ivec;
if(a.size() > 1) {
PObject *p1 = a[1];
if(p1->generateOctetsWith(ipsec_ivec, 0)) {
ivp = ipsec_ivec.buffer();
}
}
uint32_t ivlen = ivecLength();
if(ivec) {
ivec->set(ivlen, ivp);
}
PvOctets ivwork(ivlen, ivp, true);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfDESCBC_2", "ivec",
ivwork.buffer(), ivwork.length());
#endif // ISAKMP_DBG
PvOctets *enc = new PvOctets(ivlen + lenc);
OCTSTR os = enc->buffer();
OCTSTR is = (OCTSTR)text.string();
PObject *p0 = a[0];
PvOctets ipsec_key;
p0->generateOctetsWith(ipsec_key, 0);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfDESCBC_2", "key",
ipsec_key.buffer(), ipsec_key.length());
#endif // ISAKMP_DBG
const PObject *k = &ipsec_key;
OCTSTR wp = ivwork.buffer();
memcpy(os, wp, ivlen);
os += ivlen;
if(!alignmentCheck(lenc, a)) {
MfCrypt::encrypt(os, is, lenc, k, wp);
} else {
encrypt(os, is, lenc, k, wp);
}
if(DBGFLAGS('E')) {
printf("===encrypt\n");
enc->dump();
printf("\n");
}
return(enc);
}
OCTBUF *
MfDESCBC_2::decryptOctets(const OCTBUF &cipher, const PObjectList &a,
OCTBUF *&ivec) const
{
if(DBGFLAGS('D')) {
printf("===cipher\n");
cipher.dump();
printf("\n");
}
uint32_t lcipher = cipher.length();
uint32_t ivlen = ivecLength();
uint32_t ldec = lcipher - ivlen;
OCTSTR cp = (OCTSTR)cipher.string();
if(ivlen > 0) {
if(!ivec) {
ivec = new PvOctets(0);
}
ivec->set(ivlen, cp);
}
PvOctets ivwork(ivlen, cp, true);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfDESCBC_2", "ivec",
ivwork.buffer(), ivwork.length());
#endif // ISAKMP_DBG
PvOctets *dec = new PvOctets(ldec);
OCTSTR os = dec->buffer();
OCTSTR is = cp + ivlen;
PObject *p0 = a[0];
PvOctets ipsec_key;
p0->generateOctetsWith(ipsec_key, 0);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfDESCBC_2", "key",
ipsec_key.buffer(), ipsec_key.length());
#endif // ISAKMP_DBG
const PObject *k = &ipsec_key;
OCTSTR wp = ivwork.buffer();
if(!alignmentCheck(ldec, a)) {
MfCrypt::decrypt(os,is,ldec,k,wp);
} else {
decrypt(os,is,ldec,k,wp);
}
if(DBGFLAGS('D')) {
printf("===decrypt\n");
dec->dump();
printf("\n");
}
return(dec);
}
OCTBUF *
MfDES3CBC_2::encryptOctets(const OCTBUF &text,
const PObjectList &a, OCTBUF *ivec) const
{
if(DBGFLAGS('E')) {
printf("===text\n");
text.dump();
printf("\n");
}
uint32_t lenc = text.length();
OCTSTR ivp = 0;
PvOctets ipsec_ivec;
if(a.size() > 1) {
PObject *p1 = a[1];
if(p1->generateOctetsWith(ipsec_ivec, 0)) {
ivp = ipsec_ivec.buffer();
}
}
uint32_t ivlen = ivecLength();
if(ivec) {
ivec->set(ivlen, ivp);
}
PvOctets ivwork(ivlen, ivp, true);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfDES3CBC_2", "ivec",
ivwork.buffer(), ivwork.length());
#endif // ISAKMP_DBG
PvOctets *enc = new PvOctets(ivlen + lenc);
OCTSTR os = enc->buffer();
OCTSTR is = (OCTSTR)text.string();
PObject *p0 = a[0];
PvOctets ipsec_key;
p0->generateOctetsWith(ipsec_key, 0);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfDES3CBC_2", "key",
ipsec_key.buffer(), ipsec_key.length());
#endif // ISAKMP_DBG
const PObject *k = &ipsec_key;
OCTSTR wp = ivwork.buffer();
memcpy(os, wp, ivlen);
os += ivlen;
if(!alignmentCheck(lenc, a)) {
MfCrypt::encrypt(os, is, lenc, k, wp);
} else {
encrypt(os, is, lenc, k, wp);
}
if(DBGFLAGS('E')) {
printf("===encrypt\n");
enc->dump();
printf("\n");
}
return(enc);
}
OCTBUF *
MfDES3CBC_2::decryptOctets(const OCTBUF &cipher, const PObjectList &a,
OCTBUF *&ivec) const
{
if(DBGFLAGS('D')) {
printf("===cipher\n");
cipher.dump();
printf("\n");
}
uint32_t lcipher = cipher.length();
uint32_t ivlen = ivecLength();
uint32_t ldec = lcipher - ivlen;
OCTSTR cp = (OCTSTR)cipher.string();
if(ivlen > 0) {
if(!ivec) {
ivec = new PvOctets(0);
}
ivec->set(ivlen, cp);
}
PvOctets ivwork(ivlen, cp, true);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfDES3CBC_2", "ivec",
ivwork.buffer(), ivwork.length());
#endif // ISAKMP_DBG
PvOctets *dec = new PvOctets(ldec);
OCTSTR os = dec->buffer();
OCTSTR is = cp + ivlen;
PObject *p0 = a[0];
PvOctets ipsec_key;
p0->generateOctetsWith(ipsec_key, 0);
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfDES3CBC_2", "key",
ipsec_key.buffer(), ipsec_key.length());
#endif // ISAKMP_DBG
const PObject *k = &ipsec_key;
OCTSTR wp = ivwork.buffer();
if(!alignmentCheck(ldec, a)) {
MfCrypt::decrypt(os,is,ldec,k,wp);
} else {
decrypt(os,is,ldec,k,wp);
}
if(DBGFLAGS('D')) {
printf("===decrypt\n");
dec->dump();
printf("\n");
}
return(dec);
}
MfRIJNDAEL::MfRIJNDAEL(CSTR s,uint8_t k,uint8_t i,uint8_t a):MfCryptKey(s,k,i,a) {}
MfRIJNDAEL::~MfRIJNDAEL() {}
MfAuth::MfAuth(CSTR s,uint8_t i,uint8_t a):MvFunction(s),
icvLength_(i),alignUnit_(a),dummy_(0) {}
MfAuth::~MfAuth() {}
MfHMAC::MfHMAC(CSTR s,uint8_t i,uint8_t a):MfAuth(s,i,a) {}
MfHMAC::~MfHMAC() {}
MfHMACMD5::MfHMACMD5(CSTR s,uint8_t i,uint8_t a):MfHMAC(s,i,a) {}
MfHMACMD5::~MfHMACMD5() {}
MfHMACMD5_2::MfHMACMD5_2(CSTR s, uint8_t i, uint8_t a): MfHMACMD5(s, i, a) {}
MfHMACMD5_2::~MfHMACMD5_2() {}
bool
MfHMACMD5_2::checkArgument(const PFunction &o,const PObjectList &a) const
{
bool rc = true;
uint32_t n = a.size();
CSTR name = o.metaString();
if(n != 0 && n != 1) {
o.error("E %s must have 0 or 1 argument, not %d",name,n);
return(false);
}
if(n == 0) {
return(true);
}
if(!a[0]->isOctets()) {
o.error("E %s first argument has to be octet stream", name);
rc = false;
}
return(rc);
}
OCTSTR
MfHMACMD5_2::init(OCTSTR cp, const PObjectList &a) const
{
HMAC_CTX *ctx = cp != 0? (HMAC_CTX*)cp: new HMAC_CTX;
COCTSTR key = 0;
uint32_t keylen = 0;
PvOctets hash_key;
if(a.size() > 0) {
PObject *p0 = a[0];
if(p0->generateOctetsWith(hash_key, 0)) {
key = hash_key.buffer();
keylen = hash_key.length();
}
}
HMAC_Init(ctx, (OCTSTR)key, keylen, evp());
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfHMACMD5_2", "HMAC_Init(key)", key, keylen);
#endif // ISAKMP_DBG
return((OCTSTR)ctx);
}
MfHMACSHA1::MfHMACSHA1(CSTR s,uint8_t i,uint8_t a):MfHMAC(s,i,a) {}
MfHMACSHA1::~MfHMACSHA1() {}
MfHMACSHA1_2::MfHMACSHA1_2(CSTR s, uint8_t i, uint8_t a): MfHMACSHA1(s, i, a) {}
MfHMACSHA1_2::~MfHMACSHA1_2() {}
bool
MfHMACSHA1_2::checkArgument(const PFunction &o,const PObjectList &a) const
{
bool rc = true;
uint32_t n = a.size();
CSTR name = o.metaString();
if(n != 0 && n != 1) {
o.error("E %s must have 0 or 1 argument, not %d",name,n);
return(false);
}
if(n == 0) {
return(true);
}
if(!a[0]->isOctets()) {
o.error("E %s first argument has to be octet stream", name);
rc = false;
}
return(rc);
}
OCTSTR
MfHMACSHA1_2::init(OCTSTR cp, const PObjectList &a) const
{
HMAC_CTX *ctx = cp != 0? (HMAC_CTX*)cp: new HMAC_CTX;
COCTSTR key = 0;
uint32_t keylen = 0;
PvOctets hash_key;
if(a.size() > 0) {
PObject *p0 = a[0];
if(p0->generateOctetsWith(hash_key, 0)) {
key = hash_key.buffer();
keylen = hash_key.length();
}
}
HMAC_Init(ctx, (OCTSTR)key, keylen, evp());
#ifdef ISAKMP_DBG
dmp("/tmp/isakmp_dbg.txt", "MfHMACSHA1_2", "HMAC_Init(key)", key, keylen);
#endif // ISAKMP_DBG
return((OCTSTR)ctx);
}
MfHMACSHA2_256::MfHMACSHA2_256(CSTR s,uint8_t i,uint8_t a):MfHMAC(s,i,a) {}
MfHMACSHA2_256::~MfHMACSHA2_256() {}
MfHMACSHA2_384::MfHMACSHA2_384(CSTR s,uint8_t i,uint8_t a):MfHMAC(s,i,a) {}
MfHMACSHA2_384::~MfHMACSHA2_384() {}
MfHMACSHA2_512::MfHMACSHA2_512(CSTR s,uint8_t i,uint8_t a):MfHMAC(s,i,a) {}
MfHMACSHA2_512::~MfHMACSHA2_512() {}
MfESPPad* MfESPPad::defaultPadding_=0;
MfESPPad* MfESPPad::IKEdefaultPadding_=0;
syntax highlighted by Code2HTML, v. 0.9.1