/**
 * Decrypt data with the axolotl tunnel key.
 *
 * @param t Tunnel whose key to use.
 * @param dst Destination for the decrypted data, must contain @a size bytes.
 * @param src Source of the ciphertext. Can overlap with @c dst, must contain @a size bytes.
 * @param size Size of the @a src and @a dst buffers
 */
static void
t_ax_decrypt (struct CadetTunnel *t,
              void *dst,
              const void *src,
              size_t size)
{
  struct GNUNET_CRYPTO_SymmetricSessionKey MK;
  struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
  struct CadetTunnelAxolotl *ax;
  size_t out_size;

  ax = &t->ax;
  t_hmac_derive_key (&ax->CKr,
                     &MK,
                     "0",
                     1);
  GNUNET_CRYPTO_symmetric_derive_iv (&iv,
                                     &MK,
                                     NULL, 0,
                                     NULL);
  GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
  out_size = GNUNET_CRYPTO_symmetric_decrypt (src,
                                              size,
                                              &MK,
                                              &iv,
                                              dst);
  GNUNET_assert (out_size == size);
  t_hmac_derive_key (&ax->CKr,
                     &ax->CKr,
                     "1",
                     1);
}
예제 #2
0
static void
perfEncrypt ()
{
  unsigned int i;
  char buf[64 * 1024];
  char rbuf[64 * 1024];
  struct GNUNET_CRYPTO_SymmetricSessionKey sk;
  struct GNUNET_CRYPTO_SymmetricInitializationVector iv;

  GNUNET_CRYPTO_symmetric_create_session_key (&sk);

  memset (buf, 1, sizeof (buf));
  for (i = 0; i < 1024; i++)
  {
    memset (&iv, (int8_t) i, sizeof (iv));
    GNUNET_CRYPTO_symmetric_encrypt (buf, sizeof (buf),
                               &sk, &iv,
                               rbuf);
    GNUNET_CRYPTO_symmetric_decrypt (rbuf, sizeof (buf),
                               &sk, &iv,
                               buf);
  }
  memset (rbuf, 1, sizeof (rbuf));
  GNUNET_assert (0 == memcmp (rbuf, buf, sizeof (buf)));
}
예제 #3
0
/**
 * Decrypt the given UBlock, storing the result in output.
 *
 * @param input input data
 * @param input_len number of bytes in @a input
 * @param ns public key under which the UBlock was stored
 * @param label label under which the UBlock was stored
 * @param output where to write the result, has input_len bytes
 */
void
GNUNET_FS_ublock_decrypt_ (const void *input,
			   size_t input_len,
			   const struct GNUNET_CRYPTO_EcdsaPublicKey *ns,
			   const char *label,
			   void *output)
{
  struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
  struct GNUNET_CRYPTO_SymmetricSessionKey skey;

  derive_ublock_encryption_key (&skey, &iv,
				label, ns);
  GNUNET_CRYPTO_symmetric_decrypt (input, input_len,
			     &skey, &iv,
                             output);
}
/**
 * Decrypt header with the current axolotl header key.
 *
 * @param t Tunnel whose current ax HK to use.
 * @param src Message whose header to decrypt.
 * @param dst Where to decrypt header to.
 */
static void
t_h_decrypt (struct CadetTunnel *t,
             const struct GNUNET_CADET_Encrypted *src,
             struct GNUNET_CADET_Encrypted *dst)
{
  struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
  struct CadetTunnelAxolotl *ax;
  size_t out_size;

  ax = &t->ax;
  GNUNET_CRYPTO_symmetric_derive_iv (&iv,
                                     &ax->HKr,
                                     NULL, 0,
                                     NULL);
  out_size = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns,
                                              AX_HEADER_SIZE,
                                              &ax->HKr,
                                              &iv,
                                              &dst->Ns);
  GNUNET_assert (AX_HEADER_SIZE == out_size);
}
예제 #5
0
static int
testSymcipher ()
{
    struct GNUNET_CRYPTO_SymmetricSessionKey key;
    char result[100];
    int size;
    char res[100];

    GNUNET_CRYPTO_symmetric_create_session_key (&key);
    size =
        GNUNET_CRYPTO_symmetric_encrypt (TESTSTRING, strlen (TESTSTRING) + 1, &key,
                                         (const struct
                                          GNUNET_CRYPTO_SymmetricInitializationVector *)
                                         INITVALUE, result);
    if (size == -1)
    {
        printf ("symciphertest failed: encryptBlock returned %d\n", size);
        return 1;
    }
    size =
        GNUNET_CRYPTO_symmetric_decrypt (result, size, &key,
                                         (const struct
                                          GNUNET_CRYPTO_SymmetricInitializationVector *)
                                         INITVALUE, res);
    if (strlen (TESTSTRING) + 1 != size)
    {
        printf ("symciphertest failed: decryptBlock returned %d\n", size);
        return 1;
    }
    if (0 != strcmp (res, TESTSTRING))
    {
        printf ("symciphertest failed: %s != %s\n", res, TESTSTRING);
        return 1;
    }
    else
        return 0;
}
/**
 * Decrypt and verify data with the appropriate tunnel key and verify that the
 * data has not been altered since it was sent by the remote peer.
 *
 * @param t Tunnel whose key to use.
 * @param dst Destination for the plaintext.
 * @param src Source of the message. Can overlap with @c dst.
 * @param size Size of the message.
 * @return Size of the decrypted data, -1 if an error was encountered.
 */
static ssize_t
try_old_ax_keys (struct CadetTunnel *t,
                 void *dst,
                 const struct GNUNET_CADET_Encrypted *src,
                 size_t size)
{
  struct CadetTunnelSkippedKey *key;
  struct GNUNET_ShortHashCode *hmac;
  struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
  struct GNUNET_CADET_Encrypted plaintext_header;
  struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK;
  size_t esize;
  size_t res;
  size_t len;
  unsigned int N;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Trying skipped keys\n");
  hmac = &plaintext_header.hmac;
  esize = size - sizeof (struct GNUNET_CADET_Encrypted);

  /* Find a correct Header Key */
  valid_HK = NULL;
  for (key = t->ax.skipped_head; NULL != key; key = key->next)
  {
    t_hmac (&src->Ns,
            AX_HEADER_SIZE + esize,
            0,
            &key->HK,
            hmac);
    if (0 == memcmp (hmac,
                     &src->hmac,
                     sizeof (*hmac)))
    {
      valid_HK = &key->HK;
      break;
    }
  }
  if (NULL == key)
    return -1;

  /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
  GNUNET_assert (size > sizeof (struct GNUNET_CADET_Encrypted));
  len = size - sizeof (struct GNUNET_CADET_Encrypted);
  GNUNET_assert (len >= sizeof (struct GNUNET_MessageHeader));

  /* Decrypt header */
  GNUNET_CRYPTO_symmetric_derive_iv (&iv,
                                     &key->HK,
                                     NULL, 0,
                                     NULL);
  res = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns,
                                         AX_HEADER_SIZE,
                                         &key->HK,
                                         &iv,
                                         &plaintext_header.Ns);
  GNUNET_assert (AX_HEADER_SIZE == res);

  /* Find the correct message key */
  N = ntohl (plaintext_header.Ns);
  while ( (NULL != key) &&
          (N != key->Kn) )
    key = key->next;
  if ( (NULL == key) ||
       (0 != memcmp (&key->HK,
                     valid_HK,
                     sizeof (*valid_HK))) )
    return -1;

  /* Decrypt payload */
  GNUNET_CRYPTO_symmetric_derive_iv (&iv,
                                     &key->MK,
                                     NULL,
                                     0,
                                     NULL);
  res = GNUNET_CRYPTO_symmetric_decrypt (&src[1],
                                         len,
                                         &key->MK,
                                         &iv,
                                         dst);
  delete_skipped_key (t,
                      key);
  return res;
}
예제 #7
0
/**
 * Decrypt block.
 *
 * @param block block to decrypt
 * @param zone_key public key of the zone
 * @param label the name for the records
 * @param proc function to call with the result
 * @param proc_cls closure for proc
 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was
 *        not well-formed
 */
int
GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block,
				const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key,
				const char *label,
				GNUNET_GNSRECORD_RecordCallback proc,
				void *proc_cls)
{
  size_t payload_len = ntohl (block->purpose.size) -
    sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) -
    sizeof (struct GNUNET_TIME_AbsoluteNBO);
  struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
  struct GNUNET_CRYPTO_SymmetricSessionKey skey;

  if (ntohl (block->purpose.size) <
      sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
      sizeof (struct GNUNET_TIME_AbsoluteNBO))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  derive_block_aes_key (&iv, &skey, label, zone_key);
  {
    char payload[payload_len];
    uint32_t rd_count;

    GNUNET_break (payload_len ==
		  GNUNET_CRYPTO_symmetric_decrypt (&block[1], payload_len,
					     &skey, &iv,
					     payload));
    memcpy (&rd_count,
	    payload,
	    sizeof (uint32_t));
    rd_count = ntohl (rd_count);
    if (rd_count > 2048)
    {
      /* limit to sane value */
      GNUNET_break_op (0);
      return GNUNET_SYSERR;
    }
    {
      struct GNUNET_GNSRECORD_Data rd[rd_count];
      unsigned int i;
      unsigned int j;
      unsigned int k;
      struct GNUNET_TIME_Absolute now;

      if (GNUNET_OK !=
	  GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof (uint32_t),
						&payload[sizeof (uint32_t)],
						rd_count,
						rd))
      {
	GNUNET_break_op (0);
	return GNUNET_SYSERR;
      }
      /* hide expired records */
      now = GNUNET_TIME_absolute_get ();
      j = 0;
      for (i=0;i<rd_count;i++)
      {
        if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
        {
          /* encrypted blocks must never have relative expiration times, skip! */
          GNUNET_break_op (0);
          continue;
        }

        if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD))
        {
          int include_record = GNUNET_YES;
          /* Shadow record, figure out if we have a not expired active record */
          for (k=0;k<rd_count;k++)
          {
            if (k == i)
              continue;
            if (rd[i].expiration_time < now.abs_value_us)
              include_record = GNUNET_NO; /* Shadow record is expired */
            if ((rd[k].record_type == rd[i].record_type)
                && (rd[k].expiration_time >= now.abs_value_us)
                && (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)))
              include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */
          }
          if (GNUNET_YES == include_record)
          {
            rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW_RECORD; /* Remove Flag */
            if (j != i)
              rd[j] = rd[i];
            j++;
          }
        }
        else if (rd[i].expiration_time >= now.abs_value_us)
        {
          /* Include this record */
          if (j != i)
            rd[j] = rd[i];
          j++;
        }
      }
      rd_count = j;
      if (NULL != proc)
      	proc (proc_cls, rd_count, (0 != rd_count) ? rd : NULL);
    }
  }
  return GNUNET_OK;
}
예제 #8
0
static int
verifyCrypto ()
{
    struct GNUNET_CRYPTO_SymmetricSessionKey key;
    char result[GNUNET_CRYPTO_AES_KEY_LENGTH];
    char *res;
    int ret;

    unsigned char plain[] =
    {
        29, 128, 192, 253, 74, 171, 38, 187, 84, 219, 76, 76, 209, 118, 33, 249,
        172, 124, 96, 9, 157, 110, 8, 215, 200, 63, 69, 230, 157, 104, 247, 164
    };
    unsigned char raw_key_aes[] =
    {
        106, 74, 209, 88, 145, 55, 189, 135, 125, 180, 225, 108, 183, 54, 25,
        169, 129, 188, 131, 75, 227, 245, 105, 10, 225, 15, 115, 159, 148, 184,
        34, 191
    };
    unsigned char raw_key_twofish[] =
    {
        145, 55, 189, 135, 125, 180, 225, 108, 183, 54, 25,
        169, 129, 188, 131, 75, 227, 245, 105, 10, 225, 15, 115, 159, 148, 184,
        34, 191, 106, 74, 209, 88
    };
    unsigned char encrresult[] =
    {
        155, 88, 106, 174, 124, 172, 47, 149, 85, 15, 208, 176, 65, 124, 155,
        74, 215, 25, 177, 231, 162, 109, 165, 4, 133, 165, 93, 44, 213, 77,
        206, 204, 1
    };

    res = NULL;
    ret = 0;

    memcpy (key.aes_key, raw_key_aes, GNUNET_CRYPTO_AES_KEY_LENGTH);
    memcpy (key.twofish_key, raw_key_twofish, GNUNET_CRYPTO_AES_KEY_LENGTH);
    if (GNUNET_CRYPTO_AES_KEY_LENGTH !=
            GNUNET_CRYPTO_symmetric_encrypt (plain, GNUNET_CRYPTO_AES_KEY_LENGTH, &key,
                    (const struct
                     GNUNET_CRYPTO_SymmetricInitializationVector *)
                    "testtesttesttesttesttesttesttest",
                    result))
    {
        printf ("Wrong return value from encrypt block.\n");
        ret = 1;
        goto error;
    }

    if (0 != memcmp (encrresult, result, GNUNET_CRYPTO_AES_KEY_LENGTH))
    {
        int i;
        printf ("Encrypted result wrong.\n");
        for (i=0; i<GNUNET_CRYPTO_AES_KEY_LENGTH; i++)
            printf ("%u, ", (uint8_t) result[i]);
        ret = 1;
        goto error;
    }

    res = GNUNET_malloc (GNUNET_CRYPTO_AES_KEY_LENGTH);
    if (GNUNET_CRYPTO_AES_KEY_LENGTH !=
            GNUNET_CRYPTO_symmetric_decrypt (result, GNUNET_CRYPTO_AES_KEY_LENGTH, &key,
                    (const struct
                     GNUNET_CRYPTO_SymmetricInitializationVector *)
                    "testtesttesttesttesttesttesttest", res))
    {
        printf ("Wrong return value from decrypt block.\n");
        ret = 1;
        goto error;
    }
    if (0 != memcmp (res, plain, GNUNET_CRYPTO_AES_KEY_LENGTH))
    {
        printf ("Decrypted result does not match input.\n");
        ret = 1;
    }
error:
    GNUNET_free_non_null (res);
    return ret;
}