Fixed incorrect implementation of key stuff: curve25519 and ed25519 keys are now generated separately, the pcp-proprietary "derived key" feature has been dropped.

This commit is contained in:
TLINDEN
2014-01-19 23:54:53 +01:00
parent 691786cc68
commit 79cd096be5
3 changed files with 27 additions and 84 deletions

View File

@@ -45,7 +45,7 @@ typedef unsigned int qbyte; // Quad byte = 32 bits
#define PCP_ME "Pretty Curved Privacy" #define PCP_ME "Pretty Curved Privacy"
#define PCP_KEY_VERSION 4 #define PCP_KEY_VERSION 5
#define PCP_KEY_PRIMITIVE "CURVE25519-ED25519-SALSA20-POLY1305" #define PCP_KEY_PRIMITIVE "CURVE25519-ED25519-SALSA20-POLY1305"
#define PCP_KEY_TYPE_MAINSECRET 1 #define PCP_KEY_TYPE_MAINSECRET 1

View File

@@ -80,7 +80,7 @@ struct _pcp_key_t {
byte edpub[32]; byte edpub[32];
byte edsecret[64]; byte edsecret[64];
byte nonce[24]; byte nonce[24];
byte encrypted[80]; byte encrypted[112]; // both ed+curve encrypted
char owner[255]; char owner[255];
char mail[255]; char mail[255];
char id[17]; char id[17];
@@ -113,7 +113,7 @@ typedef struct _pcp_pubkey_t pcp_pubkey_t;
void pcp_cleanhashes(); void pcp_cleanhashes();
pcp_key_t *pcpkey_new (); pcp_key_t *pcpkey_new ();
void pcp_keypairs(byte *csk, byte *cpk, byte *esk, byte *epk, byte *seed); void pcp_keypairs(byte *csk, byte *cpk, byte *esk, byte *epk);
void pcp_ed_keypairs(byte *csk, byte *esk); void pcp_ed_keypairs(byte *csk, byte *esk);
char *pcppubkey_get_art(pcp_pubkey_t *k); char *pcppubkey_get_art(pcp_pubkey_t *k);

View File

@@ -93,46 +93,32 @@ char *pcp_getkeyid(pcp_key_t *k) {
return id; return id;
} }
void pcp_keypairs(byte *csk, byte *cpk, byte *esk, byte *epk, byte *seed) { void pcp_keypairs(byte *csk, byte *cpk, byte *esk, byte *epk) {
// generate ed25519 + curve25519 keypair from random seed // generate ed25519 + curve25519 keypair from random seed
byte tmp[64]; byte *seed = urmalloc(32);
byte *tmp = urmalloc(32);
// ed25519 signing key
crypto_sign_seed_keypair(epk, esk, seed); crypto_sign_seed_keypair(epk, esk, seed);
crypto_hash_sha512(tmp, seed, 32);
// curve25519 secret key
tmp[0] &= 248; tmp[0] &= 248;
tmp[31] &= 63; tmp[31] &= 63;
tmp[31] |= 64; tmp[31] |= 64;
memcpy(csk, tmp, 32); memcpy(csk, tmp, 32);
// curve25519 public key
crypto_scalarmult_curve25519_base(cpk, csk); crypto_scalarmult_curve25519_base(cpk, csk);
memset(tmp, 0, 64); memset(tmp, 0, 32);
}
void pcp_ed_keypairs(byte *csk, byte *esk) {
// re-generate (derive) curve25519 secret from ed25519 secret
// (1st half = seed, 2nd half = pub)
byte tmp[64];
byte seed[32];
memcpy(seed, esk, 32);
crypto_hash_sha512(tmp, seed, 32);
tmp[0] &= 248;
tmp[31] &= 63;
tmp[31] |= 64;
memcpy(csk, tmp, 32);
memset(tmp, 0, 64);
} }
pcp_key_t * pcpkey_new () { pcp_key_t * pcpkey_new () {
byte pub[32] = { 0 }; byte pub[32] = { 0 };
byte secret[32] = { 0 }; byte secret[32] = { 0 };
byte edpub[32] = { 0 }; byte edpub[32] = { 0 };
byte edsec[64] = { 0 }; byte edsec[64] = { 0 };
byte *seed = urmalloc(32); pcp_keypairs(secret, pub, edsec, edpub);
pcp_keypairs(secret, pub, edsec, edpub, seed);
// fill in our struct // fill in our struct
pcp_key_t *key = urmalloc(sizeof(pcp_key_t)); pcp_key_t *key = urmalloc(sizeof(pcp_key_t));
@@ -167,14 +153,20 @@ pcp_key_t *pcpkey_encrypt(pcp_key_t *key, char *passphrase) {
unsigned char *encrypted; unsigned char *encrypted;
size_t es; size_t es;
es = pcp_sodium_mac(&encrypted, key->edsecret, 64, key->nonce, encryptkey); unsigned char *both = ucmalloc(96);
memcpy(both, key->edsecret, 64);
memcpy(&both[64], key->secret, 32);
es = pcp_sodium_mac(&encrypted, both, 96, key->nonce, encryptkey);
memset(encryptkey, 0, 32); memset(encryptkey, 0, 32);
memset(both, 0, 96);
free(encryptkey); free(encryptkey);
free(both);
if(es == 80) { if(es == 112) {
// success // success
memcpy(key->encrypted, encrypted, 80); memcpy(key->encrypted, encrypted, 112);
arc4random_buf(key->secret, 32); arc4random_buf(key->secret, 32);
arc4random_buf(key->edsecret, 64); arc4random_buf(key->edsecret, 64);
key->secret[0] = 0; key->secret[0] = 0;
@@ -195,17 +187,15 @@ pcp_key_t *pcpkey_decrypt(pcp_key_t *key, char *passphrase) {
unsigned char *decrypted; unsigned char *decrypted;
size_t es; size_t es;
es = pcp_sodium_verify_mac(&decrypted, key->encrypted, 80, key->nonce, encryptkey); es = pcp_sodium_verify_mac(&decrypted, key->encrypted, 112, key->nonce, encryptkey);
memset(encryptkey, 0, 32); memset(encryptkey, 0, 32);
free(encryptkey); free(encryptkey);
if(es == 0) { if(es == 0) {
// success // success
byte secret[32] = { 0 };
pcp_ed_keypairs(secret, decrypted);
memcpy(key->secret, secret, 32);
memcpy(key->edsecret, decrypted, 64); memcpy(key->edsecret, decrypted, 64);
memcpy(key->secret, &decrypted[64], 32);
} }
else { else {
fatal("failed to decrypt the secret key (got %d, expected 32)!\n", es); fatal("failed to decrypt the secret key (got %d, expected 32)!\n", es);
@@ -306,53 +296,6 @@ pcp_pubkey_t *pubkey2native(pcp_pubkey_t *k) {
#endif #endif
} }
pcp_key_t *pcp_derive_pcpkey (pcp_key_t *ours, char *theirs) {
byte edpub[32] = { 0 };
byte edsec[64] = { 0 };
byte pub[32] = { 0 };
byte secret[32] = { 0 };
byte *seed = ucmalloc(32);
size_t thlen = strnlen(theirs, 255);
size_t inlen = 64 + thlen;
unsigned char *both = ucmalloc(inlen);
memcpy(both, ours->edsecret, 64);
memcpy(&both[64], theirs, thlen);
if(crypto_hash_sha256(seed, both, inlen) != 0) {
fatal("Failed to generate a hash of our pub key and recipient id!\n");
goto errdp1;
}
pcp_keypairs(secret, pub, edsec, edpub, seed);
pcp_key_t * tmp = pcpkey_new ();
memcpy(tmp->secret, secret, 32);
memcpy(tmp->edpub, edpub, 32);
memcpy(tmp->edsecret, edsec, 64);
memcpy(tmp->pub, pub, 32);
memcpy(tmp->owner, ours->owner, 255);
memcpy(tmp->mail, ours->mail, 255);
memcpy(tmp->id, pcp_getkeyid(tmp), 17);
memset(both, 0, inlen);
memset(seed, 0, 32);
free(both);
free(seed);
return tmp;
errdp1:
memset(both, 0, inlen);
free(both);
return NULL;
}
void pcp_seckeyblob(void *blob, pcp_key_t *k) { void pcp_seckeyblob(void *blob, pcp_key_t *k) {
memcpy(blob, k, PCP_RAW_KEYSIZE); memcpy(blob, k, PCP_RAW_KEYSIZE);