Esempio n. 1
0
lob_t local_decrypt(local_t local, lob_t outer)
{
  uint8_t key[uECC_BYTES*2], shared[uECC_BYTES], iv[16], hash[32];
  lob_t inner, tmp;

//  * `KEY` - 21 bytes, the sender's ephemeral exchange public key in compressed format
//  * `IV` - 4 bytes, a random but unique value determined by the sender
//  * `INNER` - (minimum 21+2 bytes) the AES-128-CTR encrypted inner packet ciphertext
//  * `HMAC` - 4 bytes, the calculated HMAC of all of the previous KEY+INNER bytes

  if(outer->body_len <= (21+4+0+4)) return NULL;
  tmp = lob_new();
  if(!lob_body(tmp,NULL,outer->body_len-(4+21+4))) return lob_free(tmp);

  // get the shared secret to create the iv+key for the open aes
  uECC_decompress(outer->body,key);
  if(!uECC_shared_secret(key, local->secret, shared)) return lob_free(tmp);
  e3x_hash(shared,uECC_BYTES,hash);
  fold1(hash,hash);
  memset(iv,0,16);
  memcpy(iv,outer->body+21,4);

  // decrypt the inner
  aes_128_ctr(hash,tmp->body_len,iv,outer->body+4+21,tmp->body);

  // load inner packet
  inner = lob_parse(tmp->body,tmp->body_len);
  lob_free(tmp);
  return inner;
}
Esempio n. 2
0
local_t local_new(lob_t keys, lob_t secrets)
{
  local_t local = NULL;
  lob_t key, secret;

  if(!keys) keys = lob_linked(secrets); // for convenience
  key = lob_get_base32(keys,"1c");
  if(!key) return LOG("invalid key");

  secret = lob_get_base32(secrets,"1c");
  if(!secret) return LOG("invalid secret");

  if(key->body_len == COMP_BYTES && secret->body_len == SECRET_BYTES)
  {
    if((local = malloc(sizeof(struct local_struct))))
    {
      memset(local,0,sizeof (struct local_struct));

      // copy in key/secret data
      uECC_decompress(key->body,local->key, curve);
      memcpy(local->secret,secret->body,secret->body_len);

    }else{
      LOG("OOM");
    }
    
  }else{
    LOG("invalid sizes key %d=%d secret %d=%d",key->body_len,COMP_BYTES,secret->body_len,SECRET_BYTES);
  }

  lob_free(key);
  lob_free(secret);

  return local;
}
Esempio n. 3
0
ephemeral_t ephemeral_new(remote_t remote, lob_t outer)
{
  uint8_t ekey[uECC_BYTES*2], shared[uECC_BYTES+((uECC_BYTES+1)*2)], hash[32];
  ephemeral_t ephem;

  if(!remote) return NULL;
  if(!outer || outer->body_len < (uECC_BYTES+1)) return LOG("invalid outer");

  if(!(ephem = malloc(sizeof(struct ephemeral_struct)))) return NULL;
  memset(ephem,0,sizeof (struct ephemeral_struct));

  // create and copy in the exchange routing token
  e3x_hash(outer->body,16,hash);
  memcpy(ephem->token,hash,16);

  // generate a random seq starting point for channel IV's
  e3x_rand((uint8_t*)&(ephem->seq),4);

  // decompress the exchange key and get the shared secret
  uECC_decompress(outer->body,ekey);
  if(!uECC_shared_secret(ekey, remote->esecret, shared)) return LOG("ECDH failed");

  // combine inputs to create the digest
  memcpy(shared+uECC_BYTES,remote->ecomp,uECC_BYTES+1);
  memcpy(shared+uECC_BYTES+uECC_BYTES+1,outer->body,uECC_BYTES+1);
  e3x_hash(shared,uECC_BYTES+((uECC_BYTES+1)*2),hash);
  fold1(hash,ephem->enckey);

  memcpy(shared+uECC_BYTES,outer->body,uECC_BYTES+1);
  memcpy(shared+uECC_BYTES+uECC_BYTES+1,remote->ecomp,uECC_BYTES+1);
  e3x_hash(shared,uECC_BYTES+((uECC_BYTES+1)*2),hash);
  fold1(hash,ephem->deckey);

  return ephem;
}
Esempio n. 4
0
int 
joylink_encrypt_sub_dev_data(
        uint8_t* pBuf, 
        int buflen, 
        E_EncType enctype, 
        uint8_t* key, 
        const uint8_t* payload, 
        int length)
{
	char* psJson = (char*)payload;
	uint8_t* pOut = pBuf;
    int retlen;
    uint8_t peerPubKey[uECC_BYTES * 2] = {0};
    uint8_t secret[uECC_BYTES] = {0};

	switch (enctype)
	{
	case ET_NOTHING:
		break;
	case ET_PSKAES:
		break;
	case ET_ACCESSKEYAES:
		retlen = device_aes_encrypt(
                key, 
                16, 
                key+16, 
                (uint8_t*)psJson, 
                length, 
                pOut,
                length + 16);
		break;
	case ET_ECDH:
		memcpy(pOut, __g_ekey.devPubKeyC, uECC_BYTES + 1);
		pOut += (uECC_BYTES + 1);
		uECC_decompress(key, peerPubKey);

		uECC_shared_secret(
                peerPubKey, 
                __g_ekey.priKey, 
                secret);

		retlen = device_aes_encrypt(
                secret,
                16, 
                key + 4, 
                (const uint8_t*)psJson, 
                length, 
                pOut, 
                length + 16);
		break;
	default:
		break;
	}

	return retlen;
}
Esempio n. 5
0
local_t local_new(lob_t keys, lob_t secrets)
{
  local_t local;
  lob_t key, secret;

  if(!keys) keys = lob_linked(secrets); // for convenience
  key = lob_get_base32(keys,"1a");
  if(!key || key->body_len != uECC_BYTES+1) return LOG("invalid key %d != %d",(key)?key->body_len:0,uECC_BYTES+1);

  secret = lob_get_base32(secrets,"1a");
  if(!secret || secret->body_len != uECC_BYTES) return LOG("invalid secret len %d",(secret)?secret->body_len:0);

  if(!(local = malloc(sizeof(struct local_struct)))) return NULL;
  memset(local,0,sizeof (struct local_struct));

  // copy in key/secret data
  uECC_decompress(key->body,local->key);
  memcpy(local->secret,secret->body,secret->body_len);
  lob_free(key);
  lob_free(secret);

  return local;
}
Esempio n. 6
0
remote_t remote_new(lob_t key, uint8_t *token)
{
  uint8_t hash[32];
  remote_t remote;
  if(!key || key->body_len != uECC_BYTES+1) return LOG("invalid key %d != %d",(key)?key->body_len:0,uECC_BYTES+1);

  if(!(remote = malloc(sizeof(struct remote_struct)))) return NULL;
  memset(remote,0,sizeof (struct remote_struct));

  // copy in key and make ephemeral ones
  uECC_decompress(key->body,remote->key);
  uECC_make_key(remote->ekey, remote->esecret);
  uECC_compress(remote->ekey, remote->ecomp);
  if(token)
  {
    cipher_hash(remote->ecomp,16,hash);
    memcpy(token,hash,16);
  }

  // generate a random seq starting point for message IV's
  e3x_rand((uint8_t*)&(remote->seq),4);

  return remote;
}