bugfix in encryption key computing, added new feature: derived public keys

This commit is contained in:
TLINDEN
2013-11-02 11:02:36 +01:00
parent c93f9c6cdd
commit bf5556e1ec
29 changed files with 514 additions and 242 deletions

View File

@@ -47,4 +47,7 @@ void fatal(const char * fmt, ...);
// fetch error
void fatals_ifany();
// reset
void fatals_reset();
#endif // _DEFINES_H

View File

@@ -17,6 +17,10 @@ void fatal(const char * fmt, ...) {
PCP_ERRSET = 1;
}
void fatals_reset() {
PCP_ERRSET = 0;
}
void fatals_ifany() {
if(PCP_ERRSET == 1) {
fprintf(stderr, PCP_ERR);

View File

@@ -1,5 +1,40 @@
#include "key.h"
unsigned char *pcp_derivekey(char *passphrase) {
unsigned char *hash32 = ucmalloc(crypto_hash_sha256_BYTES);
unsigned char *key = ucmalloc(crypto_secretbox_KEYBYTES);
size_t plen = strnlen(passphrase, 255);
unsigned char *temp = ucmalloc(crypto_hash_sha256_BYTES);
int i;
// make a hash from the passphrase and then HCYCLES times from the result
crypto_hash_sha256(temp, passphrase, plen);
for(i=0; i<HCYCLES; ++i) {
if(crypto_hash_sha256(hash32, temp, crypto_hash_sha256_BYTES) == 0) {
memcpy(temp, hash32, crypto_hash_sha256_BYTES);
}
}
// turn the 32byte hash into a secret key
temp[0] &= 248;
temp[31] &= 127;
temp[31] |= 64;
memcpy(key, temp, crypto_secretbox_KEYBYTES);
memset(passphrase, 0, plen);
memset(temp, 0, crypto_hash_sha256_BYTES);
free(passphrase);
free(temp);
free(hash32);
return key;
}
char *pcp_getkeyid(pcp_key_t *k) {
uint32_t s, p;
p = jen_hash(k->public, 32, JEN_PSALT);
@@ -196,4 +231,58 @@ pcp_pubkey_t *pubkey2native(pcp_pubkey_t *k) {
return k;
}
pcp_key_t *pcp_derive_pcpkey (pcp_key_t *ours, char *theirs) {
size_t thlen = strnlen(theirs, 255);
size_t inlen = 32 + thlen;
unsigned char *both = ucmalloc(inlen);
unsigned char *hash = ucmalloc(crypto_hash_BYTES);
memcpy(both, ours->secret, 32);
memcpy(&both[32], theirs, thlen);
if(crypto_hash(hash, both, inlen) != 0) {
fatal("Failed to generate a hash of our pub key and recipient id!\n");
goto errdp1;
}
unsigned char *xor = ucmalloc(crypto_secretbox_KEYBYTES);
unsigned char *secret = ucmalloc(crypto_secretbox_KEYBYTES);
int i;
for(i=0; i<crypto_secretbox_KEYBYTES; ++i) {
xor[i] = hash[i] ^ hash[i + crypto_secretbox_KEYBYTES];
}
xor[0] &= 248;
xor[31] &= 127;
xor[31] |= 64;
memcpy(secret, xor, crypto_secretbox_KEYBYTES);
pcp_key_t * tmp = pcpkey_new ();
memcpy(tmp->secret, secret, 32);
// calculate pub from secret
crypto_scalarmult_curve25519_base(tmp->public, tmp->secret);
memcpy(tmp->owner, ours->owner, 255);
memcpy(tmp->mail, ours->mail, 255);
memcpy(tmp->id, pcp_getkeyid(tmp), 17);
memset(both, 0, inlen);
memset(xor, 0, crypto_secretbox_KEYBYTES);
memset(hash, 0, crypto_hash_BYTES);
free(both);
free(xor);
free(hash);
return tmp;
errdp1:
memset(both, 0, inlen);
free(both);
return NULL;
}

View File

@@ -113,6 +113,23 @@ unsigned char * pcp_gennonce();
void pcpedit_key(char *keyid);
// proprietary key derivation function. derives an
// secure encryption key from the given passphrase by
// calculating a SALSA20 hash from it HCYCLES times.
//
// turns the result into a proper CURVE25519 secret
// key. allocates memory for key and it is up to the
// user to free it after use.
//
// deprecation warning: maybe removed once the libsodium
// developers incorporated some key derivation function
// into libsodium. so far, there's none but word goes
// that perhaps something like scrypt() from the star
// distribution may be added in the future.
unsigned char *pcp_derivekey(char *passphrase);
pcp_key_t *pcp_derive_pcpkey (pcp_key_t *ours, char *theirs);
#ifdef __cplusplus
}
#endif

View File

@@ -2,49 +2,6 @@
unsigned char *pcp_derivekey(char *passphrase) {
unsigned char *hash64 = ucmalloc(crypto_hash_BYTES);
unsigned char *xor = ucmalloc(crypto_secretbox_KEYBYTES);
unsigned char *key = ucmalloc(crypto_secretbox_KEYBYTES);
size_t plen = strnlen(passphrase, 255);
unsigned char *temp = ucmalloc(crypto_hash_BYTES);
int i;
// make a hash from the passphrase and then HCYCLES times from the result
memcpy(temp, passphrase, plen);
for(i=0; i<HCYCLES; ++i) {
if(crypto_hash(hash64, temp, plen) == 0) {
memcpy(temp, hash64, crypto_hash_BYTES);
}
}
// xor the first half of the hash with the latter to get
// a 32 byte array
for(i=0; i<crypto_secretbox_KEYBYTES; ++i) {
xor[i] = hash64[i] ^ hash64[i + crypto_secretbox_KEYBYTES];
}
// turn the 32byte hash into a secret key
xor[0] &= 248;
xor[31] &= 127;
xor[31] |= 64;
memcpy(key, xor, crypto_secretbox_KEYBYTES);
memset(passphrase, 0, plen);
memset(temp, 0, crypto_hash_BYTES);
free(passphrase);
free(temp);
free(xor);
free(hash64);
return key;
}
size_t pcp_sodium_mac(unsigned char **cipher,
unsigned char *cleartext,
size_t clearsize,

View File

@@ -47,24 +47,7 @@ int pcp_sodium_verify_mac(unsigned char **cleartext,
unsigned char *nonce,
unsigned char *key);
// generate a nonce from random source arc4random().
// allocates memory for the returned nonce and
// it is up to the user to free it after use.
void pcp_makenonce(unsigned char **nonce);
// proprietary key derivation function. derives an
// secure encryption key from the given passphrase by
// calculating a SALSA20 hash from it HCYCLES times.
//
// turns the result into a proper CURVE25519 secret
// key. allocates memory for key and it is up to the
// user to free it after use.
//
// deprecation warning: maybe removed once the libsodium
// developers incorporated some key derivation function
// into libsodium. so far, there's none but word goes
// that perhaps something like scrypt() from the star
// distribution may be added in the future.
unsigned char *pcp_derivekey(char *passphrase);
#endif // _HAVE_PCP_MAC

View File

@@ -2,8 +2,8 @@
#define _HAVE_PCP_VERSION
#define PCP_VERSION_MAJOR 0
#define PCP_VERSION_MINOR 0
#define PCP_VERSION_PATCH 1
#define PCP_VERSION_MINOR 1
#define PCP_VERSION_PATCH 2
#define PCP_MAKE_VERSION(major, minor, patch) \
((major) * 10000 + (minor) * 100 + (patch))