mirror of
https://codeberg.org/scip/pcp.git
synced 2025-12-17 20:00:58 +01:00
bugfix in encryption key computing, added new feature: derived public keys
This commit is contained in:
@@ -47,4 +47,7 @@ void fatal(const char * fmt, ...);
|
||||
// fetch error
|
||||
void fatals_ifany();
|
||||
|
||||
// reset
|
||||
void fatals_reset();
|
||||
|
||||
#endif // _DEFINES_H
|
||||
|
||||
@@ -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);
|
||||
|
||||
89
libpcp/key.c
89
libpcp/key.c
@@ -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;
|
||||
}
|
||||
|
||||
17
libpcp/key.h
17
libpcp/key.h
@@ -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
|
||||
|
||||
43
libpcp/mac.c
43
libpcp/mac.c
@@ -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,
|
||||
|
||||
19
libpcp/mac.h
19
libpcp/mac.h
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user