author | ulf69 <ulf69> | 2004-10-16 01:06:16 (UTC) |
---|---|---|
committer | ulf69 <ulf69> | 2004-10-16 01:06:16 (UTC) |
commit | 1a7713f557e9ac6b15793808ccf665d6de782035 (patch) (side-by-side diff) | |
tree | 5e44005fa1fe707f680c7250df0367097d003f8a | |
parent | a6b0eba5c1aac3ba170b99c2b773fcabe10d8a40 (diff) | |
download | kdepimpi-1a7713f557e9ac6b15793808ccf665d6de782035.zip kdepimpi-1a7713f557e9ac6b15793808ccf665d6de782035.tar.gz kdepimpi-1a7713f557e9ac6b15793808ccf665d6de782035.tar.bz2 |
*** empty log message ***
-rw-r--r-- | pwmanager/pwmanager/libgcryptif.cpp | 430 | ||||
-rw-r--r-- | pwmanager/pwmanager/libgcryptif.h | 13 |
2 files changed, 21 insertions, 422 deletions
diff --git a/pwmanager/pwmanager/libgcryptif.cpp b/pwmanager/pwmanager/libgcryptif.cpp index 6f3a994..8175510 100644 --- a/pwmanager/pwmanager/libgcryptif.cpp +++ b/pwmanager/pwmanager/libgcryptif.cpp @@ -1,506 +1,100 @@ /*************************************************************************** * * * copyright (C) 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * hashPassphrase() is derived from GnuPG and is * * Copyright (C) 1998, 1999, 2000, 2001, 2003 * * Free Software Foundation, Inc. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ +/*************************************************************************** + * copyright (C) 2004 by Ulf Schenk + * This file is originaly based on version 2.0 of pwmanager + * and was modified to run on embedded devices that run microkde + * + * $Id$ + **************************************************************************/ + #include "libgcryptif.h" #ifdef CONFIG_PWMANAGER_GCRY #include "pwmdoc.h" #include "randomizer.h" #include <gcrypt.h> -PwMerror LibGCryptIf::encrypt(unsigned char **outBuf, - size_t *outBufLen, - unsigned char *inBuf, - size_t inBufLen, - const unsigned char *key, - size_t keylen, - char _algo) -{ - PwMerror ret = e_success; - gcry_error_t err; - gcry_cipher_hd_t handle; - size_t blklen; - size_t unpaddedLen = inBufLen; - size_t cipherKeylen; - unsigned char *hashedKey; - unsigned char salt[STRING2KEY_SALTLEN]; - int algo = mapCipherId(_algo); - - if (!inBufLen || !keylen) - return e_invalidArg; - - // test if algo is ready for encryption - err = gcry_cipher_algo_info(algo, - GCRYCTL_TEST_ALGO, - 0, 0); - if (err != GPG_ERR_NO_ERROR) { - printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_TEST_ALGO failed: ") - + gcry_strerror(err)); - ret = e_cryptNotImpl; - goto out; - } - // get the algo block length - err = gcry_cipher_algo_info(algo, - GCRYCTL_GET_BLKLEN, - 0, - &blklen); - if (err != GPG_ERR_NO_ERROR) { - printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_BLKLEN failed: ") - + gcry_strerror(err)); - ret = e_cryptNotImpl; - goto out; - } - /* double check if we have enough space. - * We have only 1024 extra bytes for padding and salt. - */ - BUG_ON(blklen > 1024 - STRING2KEY_SALTLEN); - // get the algo key length - err = gcry_cipher_algo_info(algo, - GCRYCTL_GET_KEYLEN, - 0, - &cipherKeylen); - if (err != GPG_ERR_NO_ERROR) { - printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_KEYLEN failed: ") - + gcry_strerror(err)); - ret = e_cryptNotImpl; - goto out; - } - // now open the algo and get a handle - err = gcry_cipher_open(&handle, - algo, - GCRY_CIPHER_MODE_CBC, - 0); - if (err != GPG_ERR_NO_ERROR) { - printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_open() failed: ") - + gcry_strerror(err)); - ret = e_cryptNotImpl; - goto out; - } - // hash the "key" to a fixed size hash matching "cipherKeylen" - hashedKey = new unsigned char[cipherKeylen]; - hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, true); - // so now set the hashed key - err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen); - if (err != GPG_ERR_NO_ERROR) { - printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_setkey() failed: ") - + gcry_strerror(err)); - ret = e_cryptNotImpl; - delete [] hashedKey; - goto out_close; - } - delete [] hashedKey; - /* allocate a buffer for the encrypted data. - * The size of the buffer is the inBuf length, but blklen - * aligned and plus the length of the salt, that is appended. - */ - *outBufLen = getBufLen(unpaddedLen, blklen) + STRING2KEY_SALTLEN; - *outBuf = new unsigned char[*outBufLen]; - padData(inBuf, unpaddedLen, blklen); - // encrypt the padded data - err = gcry_cipher_encrypt(handle, - *outBuf, - *outBufLen - STRING2KEY_SALTLEN, - inBuf, - *outBufLen - STRING2KEY_SALTLEN); - if (err != GPG_ERR_NO_ERROR) { - printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ") - + gcry_strerror(err)); - ret = e_cryptNotImpl; - goto out_delete; - } - // append the salt to the encrypted data - memcpy(*outBuf + *outBufLen - STRING2KEY_SALTLEN, salt, STRING2KEY_SALTLEN); - goto out_close; -out_delete: - delete [] *outBuf; -out_close: - gcry_cipher_close(handle); -out: - return ret; -} - -PwMerror LibGCryptIf::decrypt(unsigned char **outBuf, - size_t *outBufLen, - const unsigned char *inBuf, - size_t inBufLen, - const unsigned char *key, - size_t keylen, - char _algo) -{ - PwMerror ret = e_success; - gcry_error_t err; - gcry_cipher_hd_t handle; - size_t cipherKeylen; - unsigned char *hashedKey; - unsigned char salt[STRING2KEY_SALTLEN]; - int algo = mapCipherId(_algo); - - if (!inBufLen || !keylen) - return e_invalidArg; - - // test if algo is ready for encryption - err = gcry_cipher_algo_info(algo, - GCRYCTL_TEST_ALGO, - 0, 0); - if (err != GPG_ERR_NO_ERROR) { - printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_TEST_ALGO failed: ") - + gcry_strerror(err)); - ret = e_cryptNotImpl; - goto out; - } - // get algo key length - err = gcry_cipher_algo_info(algo, - GCRYCTL_GET_KEYLEN, - 0, - &cipherKeylen); - if (err != GPG_ERR_NO_ERROR) { - printDebug(string("LibGCryptIf::doDecrypt(): GCRYCTL_GET_KEYLEN failed: ") - + gcry_strerror(err)); - ret = e_cryptNotImpl; - goto out; - } - // extract the salt of the encrypted data buffer - memcpy(salt, inBuf + inBufLen - STRING2KEY_SALTLEN, STRING2KEY_SALTLEN); - // open the algo and get a handle - err = gcry_cipher_open(&handle, - algo, - GCRY_CIPHER_MODE_CBC, - 0); - if (err != GPG_ERR_NO_ERROR) { - printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_open() failed: ") - + gcry_strerror(err)); - ret = e_cryptNotImpl; - goto out; - } - // hash the "key" to a fixed size hash matching "cipherKeylen" - hashedKey = new unsigned char[cipherKeylen]; - hashPassphrase(key, keylen, salt, hashedKey, cipherKeylen, false); - // so now set the hashed key - err = gcry_cipher_setkey(handle, hashedKey, cipherKeylen); - if (err != GPG_ERR_NO_ERROR) { - printDebug(string("LibGCryptIf::doDecrypt(): gcry_cipher_setkey() failed: ") - + gcry_strerror(err)); - ret = e_cryptNotImpl; - delete [] hashedKey; - goto out_close; - } - delete [] hashedKey; - *outBufLen = inBufLen - STRING2KEY_SALTLEN; - *outBuf = new unsigned char[*outBufLen]; - // decrypt the data - err = gcry_cipher_decrypt(handle, - *outBuf, - *outBufLen, - inBuf, - *outBufLen); - if (err != GPG_ERR_NO_ERROR) { - printDebug(string("LibGCryptIf::doEncrypt(): gcry_cipher_encrypt() failed: ") - + gcry_strerror(err)); - ret = e_cryptNotImpl; - goto out_delete; - } - // remove all random padding - unpadData(*outBuf, outBufLen); - goto out_close; -out_delete: - delete [] *outBuf; -out_close: - gcry_cipher_close(handle); -out: - return ret; -} - -PwMerror LibGCryptIf::hash(unsigned char **outBuf, - size_t *outBufLen, - const unsigned char *inBuf, - size_t inBufLen, - char _algo) -{ - PwMerror ret = e_success; - unsigned int hashLen; - int algo = mapHashId(_algo); - - hashLen = gcry_md_get_algo_dlen(algo); - *outBufLen = hashLen; - *outBuf = new unsigned char[*outBufLen]; - gcry_md_hash_buffer(algo, - *outBuf, - inBuf, - inBufLen); - return ret; -} +#ifdef PWM_EMBEDDED +#include <pwmprefs.h> +#endif -unsigned int LibGCryptIf::hashLength(char _algo) -{ - unsigned int ret; - int algo = mapHashId(_algo); - ret = gcry_md_get_algo_dlen(algo); - return ret; -} - -int LibGCryptIf::mapCipherId(char algo) -{ - switch (algo) { - case PWM_CRYPT_AES128: - return GCRY_CIPHER_AES; - case PWM_CRYPT_AES192: - return GCRY_CIPHER_AES192; - case PWM_CRYPT_AES256: - return GCRY_CIPHER_AES256; - case PWM_CRYPT_3DES: - return GCRY_CIPHER_3DES; - case PWM_CRYPT_TWOFISH: - return GCRY_CIPHER_TWOFISH; - case PWM_CRYPT_TWOFISH128: - return GCRY_CIPHER_TWOFISH128; - default: - BUG(); - } - return GCRY_CIPHER_NONE; -} - -int LibGCryptIf::mapHashId(char algo) -{ - switch (algo) { - case PWM_HASH_SHA1: - return GCRY_MD_SHA1; - case PWM_HASH_SHA256: - return GCRY_MD_SHA256; - case PWM_HASH_SHA384: - return GCRY_MD_SHA384; - case PWM_HASH_SHA512: - return GCRY_MD_SHA512; - case PWM_HASH_MD5: - return GCRY_MD_MD5; - case PWM_HASH_RMD160: - return GCRY_MD_RMD160; - case PWM_HASH_TIGER: - return GCRY_MD_TIGER; - default: - BUG(); - } - return GCRY_MD_NONE; -} - -bool LibGCryptIf::hashPassphrase(const unsigned char *pw, - size_t pwlen, - unsigned char *salt, - unsigned char *key, - size_t keylen, - bool create) -{ - DEK dek; - STRING2KEY s2k; - bool ret; - - dek.keylen = keylen; - s2k.mode = 1; - s2k.hash_algo = mapHashId(conf()->confGlobHashAlgo()); - s2k.count = 0; - if (!create) - memcpy(s2k.salt, salt, STRING2KEY_SALTLEN); - ret = doHashPassphrase(&dek, - pw, - pwlen, - &s2k, - create); - if (!ret) - goto out; - memcpy(key, dek.key, dek.keylen); - if (create) - memcpy(salt, s2k.salt, STRING2KEY_SALTLEN); -out: - return ret; -} - - -bool LibGCryptIf::doHashPassphrase(DEK *dek, - const unsigned char *pw, - size_t pwlen, - STRING2KEY *s2k, - bool create) -{ - // This function is derived from GnuPG-1.2.5-rc2 - gcry_md_hd_t md; - gcry_error_t err; - bool ret = true; - size_t pass, i; - size_t used = 0; - - PWM_ASSERT(s2k->hash_algo); - BUG_ON(!(dek->keylen > 0 && dek->keylen <= array_size(dek->key))); - - err = gcry_md_open(&md, s2k->hash_algo, 0); - if (err != GPG_ERR_NO_ERROR) { - ret = false; - goto out; - } - for (pass = 0; used < dek->keylen; pass++) { - if (pass) { - gcry_md_reset(md); - for (i = 0; i < pass; i++) // preset the hash context - gcry_md_putc(md, 0); - } - if (s2k->mode == 1 || s2k->mode == 3) { - size_t len2 = pwlen + 8; - size_t count = len2; - - if (create && !pass) { - Randomizer *rnd = Randomizer::obj(); - const unsigned int salt_len = 8; - string rndBuf(rnd->genRndBuf(salt_len)); - memcpy(s2k->salt, rndBuf.c_str(), salt_len); - if (s2k->mode == 3) - s2k->count = 96; // 65536 iterations - } - if (s2k->mode == 3) { - count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6); - if (count < len2) - count = len2; - } - // a little bit complicated because we need a ulong for count - while (count > len2) { // maybe iterated+salted - gcry_md_write(md, s2k->salt, 8); - gcry_md_write(md, pw, pwlen); - count -= len2; - } - if (count < 8) { - gcry_md_write(md, s2k->salt, count); - } else { - gcry_md_write(md, s2k->salt, 8); - count -= 8; - gcry_md_write(md, pw, count); - } - } else - gcry_md_write(md, pw, pwlen); - gcry_md_final(md); - i = gcry_md_get_algo_dlen(s2k->hash_algo); - if (i > dek->keylen - used) - i = dek->keylen - used; - memcpy(dek->key+used, gcry_md_read(md, s2k->hash_algo), i); - used += i; - } - gcry_md_close(md); -out: - return ret; -} - -void LibGCryptIf::padData(unsigned char *buf, - size_t bufLen, - size_t boundary) -{ - size_t numPadBytes = boundary - ((bufLen + 1) % boundary); - buf[bufLen] = static_cast<char>(0x01); - size_t i = 0; - Randomizer *rnd = Randomizer::obj(); - char c; - unsigned char *b; - while (i < numPadBytes) { - c = rnd->genRndChar(); - if (c == static_cast<char>(0x01)) - continue; - b = buf + bufLen + 1 + i; - *b = c; - ++i; - } -} - -void LibGCryptIf::unpadData(const unsigned char *buf, - size_t *bufLen) -{ - size_t pos; - BUG_ON(*bufLen % 8); - pos = *bufLen - 1; - while (buf[pos] != static_cast<char>(0x01)) { - BUG_ON(!pos); - --pos; - } - *bufLen = pos; -} - -#endif // CONFIG_PWMANAGER_GCRY - -#ifdef CONFIG_PWMANAGER_CRYPTO - -#include "pwmdoc.h" -#include "randomizer.h" - -#include <openssl/crypto.h> PwMerror LibGCryptIf::encrypt(unsigned char **outBuf, size_t *outBufLen, unsigned char *inBuf, size_t inBufLen, const unsigned char *key, size_t keylen, char _algo) { PwMerror ret = e_success; gcry_error_t err; gcry_cipher_hd_t handle; size_t blklen; size_t unpaddedLen = inBufLen; size_t cipherKeylen; unsigned char *hashedKey; unsigned char salt[STRING2KEY_SALTLEN]; int algo = mapCipherId(_algo); if (!inBufLen || !keylen) return e_invalidArg; // test if algo is ready for encryption err = gcry_cipher_algo_info(algo, GCRYCTL_TEST_ALGO, 0, 0); if (err != GPG_ERR_NO_ERROR) { printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_TEST_ALGO failed: ") + gcry_strerror(err)); ret = e_cryptNotImpl; goto out; } // get the algo block length err = gcry_cipher_algo_info(algo, GCRYCTL_GET_BLKLEN, 0, &blklen); if (err != GPG_ERR_NO_ERROR) { printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_BLKLEN failed: ") + gcry_strerror(err)); ret = e_cryptNotImpl; goto out; } /* double check if we have enough space. * We have only 1024 extra bytes for padding and salt. */ BUG_ON(blklen > 1024 - STRING2KEY_SALTLEN); // get the algo key length err = gcry_cipher_algo_info(algo, GCRYCTL_GET_KEYLEN, 0, &cipherKeylen); if (err != GPG_ERR_NO_ERROR) { printDebug(string("LibGCryptIf::doEncrypt(): GCRYCTL_GET_KEYLEN failed: ") + gcry_strerror(err)); ret = e_cryptNotImpl; goto out; } // now open the algo and get a handle err = gcry_cipher_open(&handle, algo, GCRY_CIPHER_MODE_CBC, 0); if (err != GPG_ERR_NO_ERROR) { @@ -790,66 +384,66 @@ bool LibGCryptIf::doHashPassphrase(DEK *dek, count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6); if (count < len2) count = len2; } // a little bit complicated because we need a ulong for count while (count > len2) { // maybe iterated+salted gcry_md_write(md, s2k->salt, 8); gcry_md_write(md, pw, pwlen); count -= len2; } if (count < 8) { gcry_md_write(md, s2k->salt, count); } else { gcry_md_write(md, s2k->salt, 8); count -= 8; gcry_md_write(md, pw, count); } } else gcry_md_write(md, pw, pwlen); gcry_md_final(md); i = gcry_md_get_algo_dlen(s2k->hash_algo); if (i > dek->keylen - used) i = dek->keylen - used; memcpy(dek->key+used, gcry_md_read(md, s2k->hash_algo), i); used += i; } gcry_md_close(md); out: return ret; } void LibGCryptIf::padData(unsigned char *buf, size_t bufLen, size_t boundary) { size_t numPadBytes = boundary - ((bufLen + 1) % boundary); buf[bufLen] = static_cast<char>(0x01); size_t i = 0; Randomizer *rnd = Randomizer::obj(); char c; unsigned char *b; while (i < numPadBytes) { c = rnd->genRndChar(); if (c == static_cast<char>(0x01)) continue; b = buf + bufLen + 1 + i; *b = c; ++i; } } void LibGCryptIf::unpadData(const unsigned char *buf, size_t *bufLen) { size_t pos; BUG_ON(*bufLen % 8); pos = *bufLen - 1; while (buf[pos] != static_cast<char>(0x01)) { BUG_ON(!pos); --pos; } *bufLen = pos; } -#endif // CONFIG_PWMANAGER_CRYPTO +#endif // CONFIG_PWMANAGER_GCRY diff --git a/pwmanager/pwmanager/libgcryptif.h b/pwmanager/pwmanager/libgcryptif.h index 7390827..ce76675 100644 --- a/pwmanager/pwmanager/libgcryptif.h +++ b/pwmanager/pwmanager/libgcryptif.h @@ -1,89 +1,94 @@ /*************************************************************************** * * * copyright (C) 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * hashPassphrase() is derived from GnuPG and is * * Copyright (C) 1998, 1999, 2000, 2001, 2003 * * Free Software Foundation, Inc. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ +/*************************************************************************** + * copyright (C) 2004 by Ulf Schenk + * This file is originaly based on version 2.0 of pwmanager + * and was modified to run on embedded devices that run microkde + * + * $Id$ + **************************************************************************/ + #ifndef __LIBGCRYPTIF_H #define __LIBGCRYPTIF_H #include "pwmexception.h" -//US ENH: should we put this better into globalstuff.h? -#define CONFIG_PWMANAGER_CRYPTO - //#undef CONFIG_PWMANAGER_GCRY // for debugging only. -#if defined CONFIG_PWMANAGER_GCRY || defined CONFIG_PWMANAGER_CRYPTO +#ifdef CONFIG_PWMANAGER_GCRY #include <stddef.h> #include <sys/types.h> #include <stdint.h> #define STRING2KEY_SALTLEN 8 /** interface class for the libgcrypt cipher and hash algorithms * NOTE: Always allocate 1024 extra bytes for the inBuf (for padding) */ class LibGCryptIf { protected: struct STRING2KEY { int mode; int hash_algo; uint8_t salt[STRING2KEY_SALTLEN]; uint32_t count; }; struct DEK { size_t keylen; uint8_t key[32]; // this is the largest used keylen (256 bit) }; public: LibGCryptIf() { } /** is libgcrypt available? */ static bool available() { return true; } /** encrypt data. _algo is the PWM_CRYPT_* ID * of the algorithm. */ PwMerror encrypt(unsigned char **outBuf, size_t *outBufLen, unsigned char *inBuf, size_t inBufLen, const unsigned char *key, size_t keylen, char _algo); /** decrypt data. _algo is the PWM_CRYPT_* ID * of the algorithm. */ PwMerror decrypt(unsigned char **outBuf, size_t *outBufLen, const unsigned char *inBuf, size_t inBufLen, const unsigned char *key, size_t keylen, char _algo); /** hash data. _algo is the PWM_HASH_* ID of the hash */ PwMerror hash(unsigned char **outBuf, size_t *outBufLen, const unsigned char *inBuf, size_t inBufLen, char _algo); /** returns the length of the hash. _algo is the PWM_HASH_* * id of the hash. returns 0 on error. */ unsigned int hashLength(char _algo); protected: /** returns the total buffer length */ |