Пример #1
0
int
crypto_box_open_afternm(unsigned char *m, const unsigned char *c,
                        unsigned long long clen, const unsigned char *n,
                        const unsigned char *k)
{
    return crypto_box_curve25519xsalsa20poly1305_open_afternm(m, c, clen, n, k);
}
int
crypto_box_curve25519xsalsa20poly1305_open(
    unsigned char *m, const unsigned char *c, unsigned long long clen,
    const unsigned char *n, const unsigned char *pk, const unsigned char *sk)
{
    unsigned char k[crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES];
    int           ret;

    if (crypto_box_curve25519xsalsa20poly1305_beforenm(k, pk, sk) != 0) {
        return -1;
    }
    ret = crypto_box_curve25519xsalsa20poly1305_open_afternm(m, c, clen, n, k);
    sodium_memzero(k, sizeof k);

    return ret;
}
Пример #3
0
/**
 * Decrypt and authenticate.
 *
 * @param nonce a 24 byte number, may be random, cannot repeat.
 * @param msg a message to encipher and authenticate.
 * @param secret a shared secret.
 * @return 0 if decryption is succeddful, otherwise -1.
 */
static inline int decryptRndNonce(uint8_t nonce[24],
                                  struct Message* msg,
                                  uint8_t secret[32])
{
    if (msg->length < 16) {
        return -1;
    }
    assert(msg->padding >= 16);
    uint8_t* startAt = msg->bytes - 16;
    uint8_t paddingSpace[16];
    memcpy(paddingSpace, startAt, 16);
    memset(startAt, 0, 16);
    if (crypto_box_curve25519xsalsa20poly1305_open_afternm(
            startAt, startAt, msg->length + 16, nonce, secret) != 0)
    {
        return -1;
    }

    memcpy(startAt, paddingSpace, 16);
    Message_shift(msg, -16);
    return 0;
}
Пример #4
0
static int proto_decode(sigma_proto *instance, unsigned char* input, unsigned char* output, unsigned int len)
{
	if ((len - crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES) > MAX_BUFFER_SIZE)
	{
		fprintf(stderr, "Decryption failed (packet length %i is above MAX_BUFFER_SIZE %i)\n", (len - crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES), MAX_BUFFER_SIZE);
		return 0;
	}
	
	if (len < crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES)
	{
		fprintf(stderr, "Short packet received: %d\n", len);
		return 0;
	}
	
	unsigned char tempbuffer[len + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES], tempbufferout[len + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES];
	
	memset(tempbuffer, 0, crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES);
	memcpy(tempbuffer + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES, input, len);

	int result = crypto_box_curve25519xsalsa20poly1305_open_afternm(
		tempbufferout,
		tempbuffer,
		len + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES,
		n,
		((sigma_proto_nacl*) instance)->precomp
	);
	
	if (result)
	{
		fprintf(stderr, "Decryption failed (length %i, given result %i)\n", len, result);
		return 0;
	}
	
	memcpy(output, tempbufferout + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, len - crypto_box_curve25519xsalsa20poly1305_ZEROBYTES + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES);
	
	return len - crypto_box_curve25519xsalsa20poly1305_ZEROBYTES + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES;
}
Пример #5
0
/**
 * Decrypt and authenticate.
 *
 * @param nonce a 24 byte number, may be random, cannot repeat.
 * @param msg a message to encipher and authenticate.
 * @param secret a shared secret.
 * @return 0 if decryption is succeddful, otherwise -1.
 */
static inline Gcc_USE_RET int decryptRndNonce(uint8_t nonce[24],
                                              struct Message* msg,
                                              uint8_t secret[32])
{
    if (msg->length < 16) {
        return -1;
    }
    Assert_true(msg->padding >= 16);
    uint8_t* startAt = msg->bytes - 16;
    uint8_t paddingSpace[16];
    Bits_memcpyConst(paddingSpace, startAt, 16);
    Bits_memset(startAt, 0, 16);
    if (!Defined(NSA_APPROVED)) {
        if (crypto_box_curve25519xsalsa20poly1305_open_afternm(
                startAt, startAt, msg->length + 16, nonce, secret) != 0)
        {
            return -1;
        }
    }

    Bits_memcpyConst(startAt, paddingSpace, 16);
    Message_shift(msg, -16, NULL);
    return 0;
}
Пример #6
0
int overlay_mdp_decrypt(struct overlay_frame *f, overlay_mdp_frame *mdp)
{
  IN();

  int len=f->payload->sizeLimit - f->payload->position;
  unsigned char *b = NULL;
  unsigned char plain_block[len+16];

  /* Indicate MDP message type */
  mdp->packetTypeAndFlags=MDP_TX;
  
  switch(f->modifiers&OF_CRYPTO_BITS)  {
  case 0: 
    /* get payload */
    b=&f->payload->bytes[f->payload->position];
    mdp->packetTypeAndFlags|=MDP_NOCRYPT|MDP_NOSIGN;
    break;
  case OF_CRYPTO_CIPHERED:
    RETURN(WHY("decryption not implemented"));
      
  case OF_CRYPTO_SIGNED:
    {
      /* This call below will dispatch the request for the SAS if we don't
	 already have it.  In the meantime, we just drop the frame if the SAS
	 is not available. */
      
      if (!f->source->sas_valid){
	keyring_send_sas_request(f->source);
	RETURN(WHY("SAS key not currently on record, cannot verify"));
      }
      
      /* get payload and following compacted signature */
      b=&f->payload->bytes[f->payload->position];
      len=f->payload->sizeLimit - f->payload->position - crypto_sign_edwards25519sha512batch_BYTES;

      /* reconstitute signature by putting hash between two halves of signature */
      unsigned char signature[crypto_hash_sha512_BYTES
			      +crypto_sign_edwards25519sha512batch_BYTES];
      bcopy(&b[len],&signature[0],32);
      
      crypto_hash_sha512(&signature[32],b,len);
      if (0) dump("hash for verification",&signature[32],crypto_hash_sha512_BYTES);
      
      bcopy(&b[len+32],&signature[32+crypto_hash_sha512_BYTES],32);
      
      /* verify signature */
      unsigned char m[crypto_hash_sha512_BYTES];
      unsigned long long  mlen=0;
      int result
	=crypto_sign_edwards25519sha512batch_open(m,&mlen,
						  signature,sizeof(signature),
						  f->source->sas_public);
      if (result) {
	WHY("Signature verification failed");
	dump("data", b, len);
	dump("signature", signature, sizeof(signature));
	RETURN(-1);
      } else if (0) DEBUG("signature check passed");
    }    
    mdp->packetTypeAndFlags|=MDP_NOCRYPT; 
    break;
  case OF_CRYPTO_CIPHERED|OF_CRYPTO_SIGNED:
    {
      if (0) DEBUGF("crypted MDP frame for %s", alloca_tohex_sid(mdp->out.dst.sid));

      unsigned char *k=keyring_get_nm_bytes(&mdp->out.dst,&mdp->out.src);
      unsigned char *nonce=&f->payload->bytes[f->payload->position];
      int nb=crypto_box_curve25519xsalsa20poly1305_NONCEBYTES;
      int zb=crypto_box_curve25519xsalsa20poly1305_ZEROBYTES;
      if (!k) 
	RETURN(WHY("I don't have the private key required to decrypt that"));
      bzero(&plain_block[0],crypto_box_curve25519xsalsa20poly1305_ZEROBYTES-16);
      int cipher_len=f->payload->sizeLimit - f->payload->position - nb;
      bcopy(&f->payload->bytes[nb + f->payload->position],&plain_block[16],cipher_len);
      if (0) {
	dump("nm bytes",k,crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES);
	dump("nonce",nonce,crypto_box_curve25519xsalsa20poly1305_NONCEBYTES);
	dump("cipher block",&plain_block[16],cipher_len); 
      }
      if (crypto_box_curve25519xsalsa20poly1305_open_afternm
	  (plain_block,plain_block,cipher_len+16,nonce,k)) {
	RETURN(WHYF("crypto_box_open_afternm() failed (forged or corrupted packet of %d bytes)",cipher_len+16));
      }
      if (0) dump("plain block",&plain_block[zb],cipher_len-16);
      b=&plain_block[zb];
      len=cipher_len-16;
      break;
    }    
  }
  
  if (!b)
    RETURN(WHY("Failed to decode mdp payload"));
  
  int version=(b[0]<<8)+b[1];
  if (version!=0x0101) RETURN(WHY("Saw unsupported MDP frame version"));
  
  /* extract MDP port numbers */
  mdp->in.src.port=(b[2]<<24)+(b[3]<<16)+(b[4]<<8)+b[5];
  mdp->in.dst.port=(b[6]<<24)+(b[7]<<16)+(b[8]<<8)+b[9];
  if (0) DEBUGF("RX mdp dst.port=%d, src.port=%d", mdp->in.dst.port, mdp->in.src.port);  
  
  mdp->in.payload_length=len-10;
  bcopy(&b[10],&mdp->in.payload[0],mdp->in.payload_length);
  
  RETURN(0);
}
Пример #7
0
int overlay_mdp_decrypt(struct overlay_frame *f, overlay_mdp_frame *mdp)
{
  IN();

  /* Indicate MDP message type */
  mdp->packetTypeAndFlags=MDP_TX;
  
  switch(f->modifiers&(OF_CRYPTO_CIPHERED|OF_CRYPTO_SIGNED))  {
  case 0: 
    /* nothing to do, b already points to the plain text */
    mdp->packetTypeAndFlags|=MDP_NOCRYPT|MDP_NOSIGN;
    RETURN(overlay_mdp_decode_header(f->payload, mdp));
      
  case OF_CRYPTO_CIPHERED:
    RETURN(WHY("decryption not implemented"));
      
  case OF_CRYPTO_SIGNED:
    {
      int len = ob_remaining(f->payload);
      if (crypto_verify_message(f->source, ob_ptr(f->payload), &len))
	RETURN(-1);
      
      mdp->packetTypeAndFlags|=MDP_NOCRYPT; 
      ob_limitsize(f->payload, len + ob_position(f->payload));
      RETURN(overlay_mdp_decode_header(f->payload, mdp));
    }
      
  case OF_CRYPTO_CIPHERED|OF_CRYPTO_SIGNED:
    {
      if (0) DEBUGF("crypted MDP frame for %s", alloca_tohex_sid(f->destination->sid));

      int nm=crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES;
      int nb=crypto_box_curve25519xsalsa20poly1305_NONCEBYTES;
      int zb=crypto_box_curve25519xsalsa20poly1305_ZEROBYTES;
      int cz=crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES;
      
      unsigned char *k=keyring_get_nm_bytes(f->destination->sid, f->source->sid);
      if (!k) 
	RETURN(WHY("I don't have the private key required to decrypt that"));
      
      if (0){
	dump("frame",&f->payload->bytes[f->payload->position],
	     ob_remaining(f->payload));
      }
      
      unsigned char *nonce=ob_get_bytes_ptr(f->payload, nb);
      if (!nonce)
	RETURN(WHYF("Expected %d bytes of nonce", nb));
      
      int cipher_len=ob_remaining(f->payload);
      unsigned char *cipher_text=ob_get_bytes_ptr(f->payload, cipher_len);
      if (!cipher_text)
	RETURN(WHYF("Expected %d bytes of cipher text", cipher_len));
      
      unsigned char plain_block[cipher_len+cz];
      
      bzero(&plain_block[0],cz);
      
      bcopy(cipher_text,&plain_block[cz],cipher_len);
      
      if (0) {
	dump("nm bytes",k,nm);
	dump("nonce",nonce,nb);
	dump("cipher block",plain_block,sizeof(plain_block)); 
      }
      cipher_len+=cz;
      
      if (crypto_box_curve25519xsalsa20poly1305_open_afternm
	  (plain_block,plain_block,cipher_len,nonce,k)) {
	RETURN(WHYF("crypto_box_open_afternm() failed (from %s, to %s, len %d)",
		    alloca_tohex_sid(f->source->sid), alloca_tohex_sid(f->destination->sid), cipher_len));
      }
      
      if (0) dump("plain block",plain_block,sizeof(plain_block));
      
      cipher_len -= zb;
      struct overlay_buffer *plaintext = ob_static(&plain_block[zb], cipher_len);
      ob_limitsize(plaintext,cipher_len);
      int ret=overlay_mdp_decode_header(plaintext, mdp);
      ob_free(plaintext);
      RETURN(ret);
    }    
  }
  RETURN(WHY("Failed to decode mdp payload"));
  OUT();
}