Work towards actually authcrypting MDP payloads.

Not complete.
This commit is contained in:
gardners 2012-04-14 02:14:41 +09:30
parent edde2ac8c9
commit ca24513599
4 changed files with 82 additions and 5 deletions

View File

@ -1142,3 +1142,21 @@ int keyring_seed(keyring_file *k)
return 0;
}
/*
The CryptoBox function of NaCl involves a scalar mult operation between the
public key of the recipient and the private key of the sender (or vice versa).
This can take about 1 cpu second on a phone, which is rather bad.
Fortunately, NaCl allows the caching of the result of this computation, which can
then be fed into the process to make it much, much faster.
Thus we need a mechanism for caching the various scalarmult results so that they
can indeed be reused.
*/
unsigned char *keyring_get_nm_bytes(sockaddr_mdp *priv,sockaddr_mdp *pub)
{
if (!priv) WHYRETNULL("priv is null");
if (!pub) WHYRETNULL("pub is null");
if (!keyring) WHYRETNULL("keyring is null");
WHYRETNULL("Not implemented");
}

View File

@ -166,6 +166,15 @@ int ob_append_byte(overlay_buffer *b,unsigned char byte)
return 0;
}
unsigned char *ob_append_space(overlay_buffer *b,int count)
{
if (ob_makespace(b,count)) { WHY("ob_makespace() failed"); return NULL; }
unsigned char *r=&b->bytes[b->length];
b->length+=count;
return r;
}
int ob_append_bytes(overlay_buffer *b,unsigned char *bytes,int count)
{
if (ob_makespace(b,count)) return WHY("ob_makespace() failed");

View File

@ -479,15 +479,61 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,
frame->prev=NULL;
frame->next=NULL;
int fe=0;
/* Work out the disposition of the frame. For now we are only worried
about the crypto matters, and not compression that may be applied
before encryption (since applying it after is useless as ciphered
text should have maximum entropy). */
switch(mdp->packetTypeAndFlags&(MDP_NOCRYPT|MDP_NOSIGN)) {
case 0: /* crypted and signed (using CryptBox authcryption primitive) */
frame->modifiers=OF_CRYPTO_SIGNED|OF_CRYPTO_CIPHERED;
op_free(frame);
return WHY("ciphered+signed MDP frames not implemented");
case 0: /* crypted and signed (using CryptoBox authcryption primitive) */
frame->modifiers=OF_CRYPTO_SIGNED|OF_CRYPTO_CIPHERED;
/* Prepare payload */
frame->payload=ob_new(1 /* frame type (MDP) */
+1 /* MDP version */
+4 /* dst port */
+4 /* src port */
+crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
+crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
+mdp->out.payload_length);
/* MDP version 1 */
fe|=ob_append_byte(frame->payload,0x01);
fe|=ob_append_byte(frame->payload,0x01);
/* Destination port */
fe|=ob_append_int(frame->payload,mdp->out.dst.port);
/* XXX we should probably pull the source port from the bindings
On that note, when a binding is granted, we should probably
provide a token that can be used to lookup the binding and
indicate which binding the packet is for? */
fe|=ob_append_int(frame->payload,0);
{
/* write cryptobox nonce */
unsigned char nonce[crypto_box_curve25519xsalsa20poly1305_NONCEBYTES];
if (urandombytes(nonce,crypto_box_curve25519xsalsa20poly1305_NONCEBYTES))
{ op_free(frame); WHY("urandombytes() failed to generate nonce"); }
fe|=
ob_append_bytes(frame->payload,nonce,crypto_box_curve25519xsalsa20poly1305_NONCEBYTES);
/* generate plain message with zero bytes and get ready to cipher it */
unsigned char plain[crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
+mdp->out.payload_length];
bzero(&plain[0],crypto_box_curve25519xsalsa20poly1305_ZEROBYTES);
bcopy(&mdp->out.payload,&plain[crypto_box_curve25519xsalsa20poly1305_ZEROBYTES],
mdp->out.payload_length);
/* get pre-computed PKxSK bytes (the slow part of auth-cryption that can be
retained and reused, and use that to do the encryption quickly. */
unsigned char *k=keyring_get_nm_bytes(&mdp->out.src,&mdp->out.dst);
if (!k) { op_free(frame); return WHY("could not compute Curve25519(NxM)"); }
/* Get pointer to place in frame where the ciphered text needs to go */
unsigned char *cipher_text=ob_append_space(frame->payload,sizeof(plain));
if (fe||(!cipher_text))
{ op_free(frame); return WHY("could not make space for ciphered text"); }
/* Actually authcrypt the payload */
if (crypto_box_afternm(cipher_text,plain,
crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
+mdp->out.payload_length,nonce,k))
{ op_free(frame); return WHY("crypto_box_afternm() failed"); }
}
break;
case MDP_NOSIGN:
/* ciphered, but not signed.

View File

@ -247,7 +247,6 @@ int keyring_find_sid(keyring_file *k,int *cn,int *in,int *kp,unsigned char *sid)
int keyring_commit(keyring_file *k);
keyring_identity *keyring_create_identity(keyring_file *k,keyring_context *c,
char *pin);
int keyring_seed(keyring_file *k);
/* Packet format:
@ -717,6 +716,7 @@ extern overlay_txqueue overlay_tx[OQ_MAX];
int setReason(char *fmt, ...);
#define WHY(X) setReason("%s:%d:%s() %s",__FILE__,__LINE__,__FUNCTION__,X)
#define WHYRETNULL(X) { setReason("%s:%d:%s() %s",__FILE__,__LINE__,__FUNCTION__,X); return NULL; }
#define WHYF(F, ...) setReason("%s:%d:%s() " F, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
overlay_buffer *ob_new(int size);
@ -728,6 +728,7 @@ int ob_unlimitsize(overlay_buffer *b);
int ob_makespace(overlay_buffer *b,int bytes);
int ob_append_byte(overlay_buffer *b,unsigned char byte);
int ob_append_bytes(overlay_buffer *b,unsigned char *bytes,int count);
unsigned char *ob_append_space(overlay_buffer *b,int count);
int ob_append_short(overlay_buffer *b,unsigned short v);
int ob_append_int(overlay_buffer *b,unsigned int v);
int ob_patch_rfs(overlay_buffer *b,int l);
@ -1068,6 +1069,7 @@ typedef struct sockaddr_mdp {
unsigned char sid[SID_SIZE];
unsigned int port;
} sockaddr_mdp;
unsigned char *keyring_get_nm_bytes(sockaddr_mdp *priv,sockaddr_mdp *pub);
#define MDP_TYPE_MASK 0xff
#define MDP_FLAG_MASK 0xff00
@ -1146,6 +1148,8 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,
int ob_bcopy(overlay_buffer *b,int from, int to, int len);
int ob_setbyte(overlay_buffer *b,int ofs,unsigned char value);
int urandombytes(unsigned char *x,unsigned long long xlen);
#ifdef MALLOC_PARANOIA
#define malloc(X) _serval_debug_malloc(X,__FILE__,__FUNCTION__,__LINE__)
#define calloc(X,Y) _serval_debug_calloc(X,Y,__FILE__,__FUNCTION__,__LINE__)