removed endian conversion code, now we just write in big-endian on output with shifts, not swaps etc

This commit is contained in:
Thomas von Dein
2016-10-20 23:14:14 +02:00
parent f664cc24c4
commit b8008d1207
14 changed files with 231 additions and 329 deletions

View File

@@ -221,30 +221,27 @@ uint64_t buffer_get64(Buffer *b) {
}
uint16_t buffer_get16na(Buffer *b) {
uint16_t i;
if(buffer_get_chunk(b, &i, 2) > 0) {
i = be16toh(i);
return i;
uint8_t bin[2];
if(buffer_get_chunk(b, bin, 2) > 0) {
return _wireto16(bin);
}
else
return 0;
}
uint32_t buffer_get32na(Buffer *b) {
uint32_t i;
if(buffer_get_chunk(b, &i, 4) > 0) {
i = be32toh(i);
return i;
uint8_t bin[4];
if(buffer_get_chunk(b, bin, 4) > 0) {
return _wireto32(bin);
}
else
return 0;
}
uint64_t buffer_get64na(Buffer *b) {
uint64_t i;
if(buffer_get_chunk(b, &i, 8) > 0) {
i = be64toh(i);
return i;
uint8_t bin[8];
if(buffer_get_chunk(b, bin, 8) > 0) {
return _wireto64(bin);
}
else
return 0;
@@ -362,19 +359,19 @@ void buffer_add64(Buffer *b, uint64_t v) {
}
void buffer_add16be(Buffer *b, uint16_t v) {
uint16_t e = v;
e = htobe16(e);
buffer_add(b, &e, 2);
uint8_t bin[2];
_16towire(v, bin);
buffer_add(b, bin, 2);
}
void buffer_add32be(Buffer *b, uint32_t v) {
uint32_t e = v;
e = htobe32(e);
buffer_add(b, &e, 4);
uint8_t bin[4];
_32towire(v, bin);
buffer_add(b, bin, 4);
}
void buffer_add64be(Buffer *b, uint64_t v) {
uint64_t e = v;
e = htobe64(e);
buffer_add(b, &e, 8);
uint8_t bin[8];
_64towire(v, bin);
buffer_add(b, bin, 8);
}

View File

@@ -202,12 +202,13 @@ size_t pcp_decrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream* out, pcp_key_t
}
/* step 3, check len recipients */
cur_bufsize = ps_read(in, &lenrec, 4); /* fread(&lenrec, 1, 4, in); */
byte li[4];
cur_bufsize = ps_read(in, li, 4); /* fread(&lenrec, 1, 4, in); */
if(cur_bufsize != 4 && !ps_end(in) && !ps_err(in)) {
fatal(ptx, "Error: input file doesn't contain recipient count\n");
goto errdef1;
}
lenrec = be32toh(lenrec);
lenrec = _wireto32(li);
if (ptx->verbose) {
fprintf(stderr, "crypto.c: input is encrypted for %ld recipients\n", (long int)lenrec);
@@ -353,10 +354,10 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t
pcp_pubkey_t *cur, *t;
size_t es;
int nrec;
uint32_t lenrec;
size_t rec_size, out_size;
byte head[1];
byte bo[4];
/*
6[1]|temp_keypair.pubkey|len(recipients)[4]|(recipients...)|(secretboxes...)
where recipients is a concatenated list of
@@ -437,9 +438,9 @@ size_t pcp_encrypt_stream(PCPCTX *ptx, Pcpstream *in, Pcpstream *out, pcp_key_t
}
/* step 3, len recipients, big endian */
lenrec = recipient_count;
lenrec = htobe32(lenrec);
ps_write(out, &lenrec, 4);
_32towire(recipient_count, bo);
ps_write(out, bo, 4);
if(ps_err(out) != 0)
goto errec1;
@@ -789,8 +790,6 @@ void pcp_rec_free(pcp_rec_t *r) {
uint64_t _get_nonce_ctr(byte *nonce) {
uint64_t ctr = 0;
uint8_t i = nonce[0];
uint16_t m16 = 0;
uint32_t m32 = 0;
if(i > 16) {
/* counter bigger than max allowed by protocol, could lead to overflow, therefore die hard here */
@@ -803,16 +802,13 @@ uint64_t _get_nonce_ctr(byte *nonce) {
ctr = nonce[1];
break;
case 2:
memcpy(&m16, &nonce[1], 2);
ctr = be16toh(m16);
ctr = _wireto16(&nonce[1]);
break;
case 4:
memcpy(&m32, &nonce[1], 4);
ctr = be32toh(m32);
ctr = _wireto32(&nonce[1]);
break;
case 8:
memcpy(&ctr, &nonce[1], 8);
ctr = be64toh(ctr);
ctr = _wireto64(&nonce[1]);
break;
}
@@ -876,25 +872,21 @@ byte *_gen_ctr_nonce(uint64_t ctr) {
uint8_t m8 = -1;
uint16_t m16 = -1;
uint32_t m32 = -1;
uint64_t m64 = -1;
uint8_t i = 1;
byte *nonce = pcp_gennonce();
if(ctr > m32) {
i = 8;
m64 = htobe64(ctr);
memcpy(&nonce[1], &m64, 8);
_64towire(ctr, &nonce[1]);
}
else if(ctr <= m32 && ctr > m16) {
i = 4;
m32 = htobe32(ctr);
memcpy(&nonce[1], &m32, 4);
_32towire(ctr, &nonce[1]);
}
else if(ctr <= m16 && ctr > m8) {
i = 2;
m16 = htobe16(ctr);
memcpy(&nonce[1], &m16, 2);
_16towire(ctr, &nonce[1]);
}
else {
i = 1;

View File

@@ -253,96 +253,77 @@ byte *pcpkey_getchecksum(pcp_key_t *k) {
}
pcp_key_t * key2be(pcp_key_t *k) {
#ifdef __CPU_IS_BIG_ENDIAN
return k;
#else
uint32_t version = k->version;
byte* p = (byte*)&version;
if(p[0] != 0) {
k->version = htobe32(k->version);
k->serial = htobe32(k->serial);
k->ctime = htobe64(k->ctime);
}
return k;
#endif
}
pcp_key_t *key2native(pcp_key_t *k) {
#ifdef __CPU_IS_BIG_ENDIAN
return k;
#else
k->version = be32toh(k->version);
k->serial = be32toh(k->serial);
k->ctime = be64toh(k->ctime);
return k;
#endif
}
pcp_pubkey_t * pubkey2be(pcp_pubkey_t *k) {
#ifdef __CPU_IS_BIG_ENDIAN
return k;
#else
uint32_t version = k->version;
byte* p = (byte*)&version;
if(p[0] != 0) {
k->version = htobe32(k->version);
k->serial = htobe32(k->serial);
k->ctime = htobe64(k->ctime);
}
return k;
#endif
}
pcp_pubkey_t *pubkey2native(pcp_pubkey_t *k) {
#ifdef __CPU_IS_BIG_ENDIAN
return k;
#else
k->version = be32toh(k->version);
k->serial = be32toh(k->serial);
k->ctime = be64toh(k->ctime);
return k;
#endif
void pcp_pubkeyblob(Buffer *b, pcp_pubkey_t *k) {
buffer_add(b, k->masterpub, LEDPUB);
buffer_add(b, k->pub, LBOXPUB);
buffer_add(b, k->edpub, LEDPUB);
buffer_add(b, k->owner, 255);
buffer_add(b, k->mail, 255);
buffer_add(b, k->id, 17);
buffer_add8(b, k->type);
buffer_add64be(b, k->ctime);
buffer_add32be(b, k->version);
buffer_add32be(b, k->serial);
buffer_add8(b, k->valid);
}
void pcp_seckeyblob(Buffer *b, pcp_key_t *k) {
buffer_add(b, k->masterpub, LEDPUB);
buffer_add(b, k->mastersecret, LEDSEC);
buffer_add(b, k->pub, LBOXPUB);
buffer_add(b, k->secret, LBOXPUB);
buffer_add(b, k->edpub, LEDPUB);
buffer_add(b, k->edsecret, LEDSEC);
buffer_add(b, k->nonce, LNONCE);
buffer_add(b, k->encrypted, LSEC);
buffer_add(b, k->owner, 255);
buffer_add(b, k->mail, 255);
buffer_add(b, k->id, 17);
buffer_add8(b, k->type);
buffer_add64(b, k->ctime);
buffer_add32(b, k->version);
buffer_add32(b, k->serial);
buffer_add64be(b, k->ctime);
buffer_add32be(b, k->version);
buffer_add32be(b, k->serial);
}
void pcp_pubkeyblob(Buffer *b, pcp_pubkey_t *k) {
buffer_add(b, k->masterpub, LEDPUB);
buffer_add(b, k->pub, LBOXPUB);
buffer_add(b, k->edpub, LEDPUB);
pcp_key_t *pcp_blob2key(Buffer *b) {
pcp_key_t *k = ucmalloc(sizeof(pcp_key_t));
buffer_get_chunk(b, k->masterpub, LEDPUB);
buffer_get_chunk(b, k->mastersecret, LEDSEC);
buffer_get_chunk(b, k->pub, LBOXPUB);
buffer_get_chunk(b, k->secret, LBOXPUB);
buffer_get_chunk(b, k->edpub, LEDPUB);
buffer_get_chunk(b, k->edsecret, LEDSEC);
buffer_get_chunk(b, k->nonce, LNONCE);
buffer_get_chunk(b, k->encrypted, LSEC);
buffer_get_chunk(b, k->owner, 255);
buffer_get_chunk(b, k->mail, 255);
buffer_get_chunk(b, k->id, 17);
buffer_add(b, k->owner, 255);
buffer_add(b, k->mail, 255);
buffer_add(b, k->id, 17);
k->type = buffer_get8(b);
k->ctime = buffer_get64na(b);
k->version = buffer_get32na(b);
k->serial = buffer_get32na(b);
buffer_add8(b, k->type);
buffer_add64(b, k->ctime);
buffer_add32(b, k->version);
buffer_add32(b, k->serial);
buffer_add8(b, k->valid);
return k;
}
pcp_pubkey_t *pcp_blob2pubkey(Buffer *b) {
pcp_pubkey_t *k = ucmalloc(sizeof(pcp_key_t));
buffer_get_chunk(b, k->masterpub, LEDPUB);
buffer_get_chunk(b, k->pub, LBOXPUB);
buffer_get_chunk(b, k->edpub, LEDPUB);
buffer_get_chunk(b, k->owner, 255);
buffer_get_chunk(b, k->mail, 255);
buffer_get_chunk(b, k->id, 17);
k->type = buffer_get8(b);
k->ctime = buffer_get64na(b);
k->version = buffer_get32na(b);
k->serial = buffer_get32na(b);
k->valid = buffer_get8(b);
return k;
}
Buffer *pcp_keyblob(void *k, int type) {

View File

@@ -23,25 +23,13 @@
#include "keysig.h"
pcp_keysig_t * keysig2be(pcp_keysig_t *s) {
#ifdef __CPU_IS_BIG_ENDIAN
_32towire(s->size, (byte *)&s->size);
return s;
#else
uint32_t size = s->size;
byte* p = (byte*)&size;
if(p[0] != 0) {
s->size = htobe32(s->size);
}
return s;
#endif
}
pcp_keysig_t *keysig2native(pcp_keysig_t *s) {
#ifdef __CPU_IS_BIG_ENDIAN
s->size = _wireto32((byte *)&s->size);
return s;
#else
s->size = be32toh(s->size);
return s;
#endif
}
Buffer *pcp_keysig2blob(pcp_keysig_t *s) {

View File

@@ -36,9 +36,9 @@ int _get_pk(Buffer *blob, pcp_pubkey_t *p) {
int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h) {
if(buffer_left(blob) >= sizeof(rfc_pub_sig_h)) {
buffer_get_chunk(blob, h, sizeof(rfc_pub_sig_h));
buffer_get_chunk(blob, h, sizeof(rfc_pub_sig_h)); /* FIXME: blog 2 struct? thafck */
h->numsubs = be16toh(h->numsubs);
h->numsubs = _wireto16((byte *)&h->numsubs);
if(h->version != EXP_SIG_VERSION) {
fatal(ptx, "Unsupported pubkey signature version %d, expected %d\n",
@@ -800,7 +800,7 @@ pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphras
cipherlen, nonce, symkey) != 0) {
fatal(ptx, "failed to decrypt the secret key file\n");
goto impserr1;
goto impserr2;
}
/* prepare the extraction buffer */
@@ -817,7 +817,8 @@ pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphras
notationlen = buffer_get16na(blob);
if(notationlen > 255) {
fatal(ptx, "Invalid notation value size for owner\n");
fatal(ptx, "Invalid notation value size for owner (got: %ld, expected: 255)\n",
notationlen);
goto impserr2;
}
else if(notationlen > 0)
@@ -825,7 +826,8 @@ pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphras
notationlen = buffer_get16na(blob);
if(notationlen > 255) {
fatal(ptx, "Invalid notation value size for mail\n");
fatal(ptx, "Invalid notation value size for mail (got: %ld, expected: 255)\n",
notationlen);
goto impserr2;
}
else if(notationlen > 0)
@@ -862,8 +864,6 @@ pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphras
buffer_free(blob);
if(symkey != NULL)
sfree(symkey);
if(clear != NULL)
free(clear);
return NULL;
}

View File

@@ -120,6 +120,74 @@ size_t _hex2bin(const char *hex_str, unsigned char *byte_array, size_t byte_arra
return byte_array_size;
}
/*
* Convert byte arrays from big endian to numbers and vice versa. Do
* not take care about host endianess. In Rob Pikes' words:
* https://commandcenter.blogspot.de/2012/04/byte-order-fallacy.html
*
* With this, we remove all calls to byte swap functions like b64toh
* and the likes. They are problematic and I really hated the ifdef
* mess in platform.h anyway.
*/
uint64_t _wireto64(byte *data) {
uint64_t i =
((uint64_t)data[7]<<0) |
((uint64_t)data[6]<<8) |
((uint64_t)data[5]<<16) |
((uint64_t)data[4]<<24) |
((uint64_t)data[3]<<32) |
((uint64_t)data[2]<<40) |
((uint64_t)data[1]<<48) |
((uint64_t)data[0]<<56);
return i;
}
uint32_t _wireto32(byte *data) {
uint32_t i =
((uint32_t)data[3]<<0) |
((uint32_t)data[2]<<8) |
((uint32_t)data[1]<<16) |
((uint32_t)data[0]<<24);
return i;
}
uint16_t _wireto16(byte *data) {
uint16_t i =
((uint16_t)data[1]<<0) |
((uint16_t)data[0]<<8);
return i;
}
void _64towire(uint64_t i, byte *data) {
data[0] = (i >> 56) & 0xFF;
data[1] = (i >> 48) & 0xFF;
data[2] = (i >> 40) & 0xFF;
data[3] = (i >> 32) & 0xFF;
data[4] = (i >> 24) & 0xFF;
data[5] = (i >> 16) & 0xFF;
data[6] = (i >> 8) & 0xFF;
data[7] = i & 0xFF;
}
void _32towire(uint32_t i, byte *data) {
data[0] = (i >> 24) & 0xFF;
data[1] = (i >> 16) & 0xFF;
data[2] = (i >> 8) & 0xFF;
data[3] = i & 0xFF;
}
void _16towire(uint16_t i, byte *data) {
data[0] = (i >> 8) & 0xFF;
data[1] = i & 0xFF;
}
/* via https://github.com/chmike/cst_time_memcmp
Licensed as:

View File

@@ -164,11 +164,10 @@ int pcpvault_addkey(PCPCTX *ptx, vault_t *vault, void *item, uint8_t type) {
itemsize = PCP_RAW_PUBKEYSIZE;
saveitem = ucmalloc(sizeof(pcp_pubkey_t));
memcpy(saveitem, item, sizeof(pcp_pubkey_t));
pubkey2be((pcp_pubkey_t *)item);
blob = buffer_new(PCP_RAW_KEYSIZE, "bs");
pcp_pubkeyblob(blob, (pcp_pubkey_t *)item);
blob = pcp_keyblob(item, type);
}
else if(type == PCP_KEYSIG_NATIVE || type == PCP_KEYSIG_PBP) {
/* FIXME: handle the same way as keys */
saveitem = ucmalloc(sizeof(pcp_keysig_t));
pcp_keysig_t *ksin = (pcp_keysig_t *)item;
pcp_keysig_t *ksout = (pcp_keysig_t *)saveitem;
@@ -183,9 +182,7 @@ int pcpvault_addkey(PCPCTX *ptx, vault_t *vault, void *item, uint8_t type) {
itemsize = PCP_RAW_KEYSIZE;
saveitem = ucmalloc(sizeof(pcp_key_t));
memcpy(saveitem, item, sizeof(pcp_key_t));
key2be((pcp_key_t *)item);
blob = pcp_keyblob(item, type);
pcp_seckeyblob(blob, (pcp_key_t *)item);
}
if(tmp != NULL) {
@@ -295,23 +292,19 @@ byte *pcpvault_create_checksum(PCPCTX *ptx) {
byte *checksum = ucmalloc(LSHA);
pcphash_iterate(ptx, k) {
key2be(k);
pcp_seckeyblob(blob, (pcp_key_t *)k);
memcpy(&data[datapos], buffer_get(blob), PCP_RAW_KEYSIZE);
memcpy(&data[datapos], buffer_get(blob), buffer_size(blob));
buffer_clear(blob);
key2native(k);
datapos += PCP_RAW_KEYSIZE;
datapos += buffer_size(blob);
}
pcp_pubkey_t *p = NULL;
pcphash_iteratepub(ptx, p) {
/* pcp_dumppubkey(p); */
pubkey2be(p);
pcp_pubkeyblob(blob, (pcp_pubkey_t *)p);
memcpy(&data[datapos], buffer_get(blob), PCP_RAW_PUBKEYSIZE);
memcpy(&data[datapos], buffer_get(blob), buffer_size(blob));
buffer_clear(blob);
pubkey2native(p);
datapos += PCP_RAW_PUBKEYSIZE;
datapos += PCP_RAW_KEYSIZE;
}
buffer_free(blob);
@@ -390,41 +383,25 @@ void pcpvault_free(vault_t *vault) {
}
vault_header_t * vh2be(vault_header_t *h) {
#ifdef __CPU_IS_BIG_ENDIAN
_32towire(h->version, (byte *)&h->version);
return h;
#else
h->version = htobe32(h->version);
return h;
#endif
}
vault_header_t * vh2native(vault_header_t *h) {
#ifdef __CPU_IS_BIG_ENDIAN
h->version = _wireto32((byte *)&h->version);
return h;
#else
h->version = be32toh(h->version);
return h;
#endif
}
vault_item_header_t * ih2be(vault_item_header_t *h) {
#ifdef __CPU_IS_BIG_ENDIAN
_32towire(h->version, (byte *)&h->version);
_32towire(h->size, (byte *)&h->size);
return h;
#else
h->version = htobe32(h->version);
h->size = htobe32(h->size);
return h;
#endif
}
vault_item_header_t * ih2native(vault_item_header_t *h) {
#ifdef __CPU_IS_BIG_ENDIAN
h->version = _wireto32((byte *)&h->version);
h->size = _wireto32((byte *)&h->size);
return h;
#else
h->version = be32toh(h->version);
h->size = be32toh(h->size);
return h;
#endif
}
@@ -449,7 +426,8 @@ int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault) {
pcp_pubkey_t *pubkey;
int bytesleft = 0;
int ksize = PCP_RAW_KEYSIGSIZE; /* smallest possbile item */
Buffer *raw = buffer_new(256, "rawin");
vault->version = header->version;
memcpy(vault->checksum, header->checksum, LSHA);
@@ -469,24 +447,23 @@ int pcpvault_fetchall(PCPCTX *ptx, vault_t *vault) {
if(item->type == PCP_KEY_TYPE_MAINSECRET ||
item->type == PCP_KEY_TYPE_SECRET) {
/* read a secret key */
key = ucmalloc(sizeof(pcp_key_t));
got = fread(key, PCP_RAW_KEYSIZE, 1, vault->fd);
key2native(key);
buffer_fd_read(raw, vault->fd, item->size);
key = pcp_blob2key(raw);
pcphash_add(ptx, (void *)key, item->type);
buffer_clear(raw);
}
else if(item->type == PCP_KEY_TYPE_PUBLIC) {
/* read a public key */
pubkey = ucmalloc(sizeof(pcp_pubkey_t));
got = fread(pubkey, PCP_RAW_PUBKEYSIZE, 1, vault->fd);
pubkey2native(pubkey);
buffer_fd_read(raw, vault->fd, item->size);
pubkey = pcp_blob2pubkey(raw);
pcphash_add(ptx, (void *)pubkey, item->type);
buffer_clear(raw);
}
else if(item->type == PCP_KEYSIG_NATIVE || item->type == PCP_KEYSIG_PBP) {
Buffer *rawks = buffer_new(256, "keysig");
buffer_fd_read(rawks, vault->fd, item->size);
pcp_keysig_t *s = pcp_keysig_new(rawks);
buffer_fd_read(raw, vault->fd, item->size);
pcp_keysig_t *s = pcp_keysig_new(raw);
pcphash_add(ptx, (void *)s, item->type);
buffer_free(rawks);
buffer_clear(raw);
}
else {
fatal(ptx, "Failed to read vault - invalid key type: %02X! at %d\n",