em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
em->iv_seed = ph->iv_seed;
esize = used - ENCRYPTED_HEADER_SIZE;
- GNUNET_CRYPTO_hmac (&n->encrypt_key,
- &ph->sequence_number,
- esize - sizeof (GNUNET_HashCode),
- &ph->hmac);
+// FIXME NILS
+// GNUNET_CRYPTO_hmac (&n->encrypt_key,
+// &ph->sequence_number,
+// esize - sizeof (GNUNET_HashCode),
+// &ph->hmac);
GNUNET_CRYPTO_hash (&ph->iv_seed, sizeof (uint32_t), &iv);
#if DEBUG_HANDSHAKE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
return;
pt = (struct EncryptedMessage *) buf;
/* validate hash */
- GNUNET_CRYPTO_hmac (&n->decrypt_key,
- &pt->sequence_number,
- size - ENCRYPTED_HEADER_SIZE - sizeof (GNUNET_HashCode), &ph);
-#if DEBUG_HANDSHAKE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "V-Hashed %u bytes of plaintext (`%s') using IV `%d'\n",
- (unsigned int) (size - ENCRYPTED_HEADER_SIZE - sizeof (GNUNET_HashCode)),
- GNUNET_h2s (&ph),
- (int) m->iv_seed);
-#endif
- if (0 != memcmp (&ph,
- &pt->hmac,
- sizeof (GNUNET_HashCode)))
- {
- /* checksum failed */
- GNUNET_break_op (0);
- return;
- }
+// FIXME NILS
+// GNUNET_CRYPTO_hmac (&n->decrypt_key,
+// &pt->sequence_number,
+// size - ENCRYPTED_HEADER_SIZE - sizeof (GNUNET_HashCode), &ph);
+//#if DEBUG_HANDSHAKE
+// GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+// "V-Hashed %u bytes of plaintext (`%s') using IV `%d'\n",
+// (unsigned int) (size - ENCRYPTED_HEADER_SIZE - sizeof (GNUNET_HashCode)),
+// GNUNET_h2s (&ph),
+// (int) m->iv_seed);
+//#endif
+// if (0 != memcmp (&ph,
+// &pt->hmac,
+// sizeof (GNUNET_HashCode)))
+// {
+// /* checksum failed */
+// GNUNET_break_op (0);
+// return;
+// }
/* validate sequence number */
snum = ntohl (pt->sequence_number);
/**
* High-quality operations are desired.
*/
- GNUNET_CRYPTO_QUALITY_STRONG
+ GNUNET_CRYPTO_QUALITY_STRONG,
+
+ /**
+ * Randomness for IVs etc. is required.
+ */
+ GNUNET_CRYPTO_QUALITY_NONCE
};
#define GNUNET_CRYPTO_RSA_KEY_LENGTH 258
+/**
+ * Length of a hash value
+ */
+#define GNUNET_CRYPTO_HASH_LENGTH 512/8
+
/**
* The private information of an RSA key pair.
*/
};
+/**
+ * @brief type for (message) authentication keys
+ */
+struct GNUNET_CRYPTO_AuthKey
+{
+ unsigned char key[GNUNET_CRYPTO_HASH_LENGTH];
+};
+
+
/* **************** Functions and Macros ************* */
void GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey
*key);
-
/**
* Check that a new session key is well-formed.
*
void *result);
+/**
+ * @brief Derive an IV
+ * @param iv initialization vector
+ * @param skey session key
+ * @param salt salt for the derivation
+ * @param salt_len size of the salt
+ * @param ... pairs of void * & size_t for context chunks, terminated by NULL
+ */
+void
+GNUNET_CRYPTO_aes_derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
+ const struct GNUNET_CRYPTO_AesSessionKey *skey, void *salt,
+ size_t salt_len, ...);
+
+
+/**
+ * @brief Derive an IV
+ * @param iv initialization vector
+ * @param skey session key
+ * @param salt salt for the derivation
+ * @param salt_len size of the salt
+ * @param argp pairs of void * & size_t for context chunks, terminated by NULL
+ */
+void
+GNUNET_CRYPTO_aes_derive_iv_v (struct GNUNET_CRYPTO_AesInitializationVector *iv,
+ const struct GNUNET_CRYPTO_AesSessionKey *skey, void *salt,
+ size_t salt_len, va_list argp);
+
+
/**
* Convert hash to ASCII encoding.
* @param block the hash code
* @param hmac where to store the hmac
*/
void
-GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AesSessionKey *key,
+GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key,
const void *plaintext,
size_t plaintext_len,
GNUNET_HashCode *hmac);
const GNUNET_HashCode * target);
+/**
+ * @brief Derive an authentication key
+ * @param key authentication key
+ * @param rkey root key
+ * @param salt salt
+ * @param salt_len size of the salt
+ * @param argp pair of void * & size_t for context chunks, terminated by NULL
+ */
+void
+GNUNET_CRYPTO_hmac_derive_key_v(struct GNUNET_CRYPTO_AuthKey *key,
+ const struct GNUNET_CRYPTO_AesSessionKey *rkey,
+ const void *salt,
+ const size_t salt_len,
+ const va_list argp);
+
+
+/**
+ * @brief Derive an authentication key
+ * @param key authentication key
+ * @param rkey root key
+ * @param salt salt
+ * @param salt_len size of the salt
+ * @param ... pair of void * & size_t for context chunks, terminated by NULL
+ */
+void
+GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key,
+ const struct GNUNET_CRYPTO_AesSessionKey *rkey,
+ const void *salt,
+ const size_t salt_len,
+ ...);
+
/**
* @brief Derive key
* @param result buffer for the derived key, allocated by caller
const void *skm, const size_t skm_len, ...);
+/**
+ * @brief Derive key
+ * @param result buffer for the derived key, allocated by caller
+ * @param out_len desired length of the derived key
+ * @param xtr_algo hash algorithm for the extraction phase, GCRY_MD_...
+ * @param prf_algo hash algorithm for the expansion phase, GCRY_MD_...
+ * @param xts salt
+ * @param xts_len length of xts
+ * @param skm source key material
+ * @param skm_len length of skm
+ * @param argp va_list of void * & size_t pairs for context chunks
+ * @return GNUNET_YES on success
+ */
+int
+GNUNET_CRYPTO_hkdf_v (void *result, const unsigned long long out_len,
+ int xtr_algo, int prf_algo, const void *xts, const size_t xts_len,
+ const void *skm, const size_t skm_len, va_list argp);
+
+
+/**
+ * @brief Derive key
+ * @param result buffer for the derived key, allocated by caller
+ * @param out_len desired length of the derived key
+ * @param xts salt
+ * @param xts_len length of xts
+ * @param skm source key material
+ * @param skm_len length of skm
+ * @param argp va_list of void * & size_t pairs for context chunks
+ * @return GNUNET_YES on success
+ */
+int
+GNUNET_CRYPTO_kdf_v (void *result, const unsigned long long out_len,
+ const void *xts, const size_t xts_len, const void *skm,
+ const size_t skm_len, va_list argp);
+
+
+/**
+ * @brief Derive key
+ * @param result buffer for the derived key, allocated by caller
+ * @param out_len desired length of the derived key
+ * @param xts salt
+ * @param xts_len length of xts
+ * @param skm source key material
+ * @param skm_len length of skm
+ * @param ... void * & size_t pairs for context chunks
+ * @return GNUNET_YES on success
+ */
+int
+GNUNET_CRYPTO_kdf (void *result, const unsigned long long out_len,
+ const void *xts, const size_t xts_len, const void *skm,
+ const size_t skm_len, ...);
+
+
/**
* Create a new private key. Caller must free return value.
*
crypto_crc.c \
crypto_hash.c \
crypto_hkdf.c \
+ crypto_kdf.c \
crypto_ksk.c \
crypto_random.c \
crypto_rsa.c \
return size;
}
+/**
+ * @brief Derive an IV
+ * @param iv initialization vector
+ * @param skey session key
+ * @param salt salt for the derivation
+ * @param salt_len size of the salt
+ * @param ... pairs of void * & size_t for context chunks, terminated by NULL
+ */
+void
+GNUNET_CRYPTO_aes_derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
+ const struct GNUNET_CRYPTO_AesSessionKey *skey, void *salt,
+ size_t salt_len, ...)
+{
+ va_list argp;
+
+ va_start (argp, salt_len);
+ GNUNET_CRYPTO_aes_derive_iv_v (iv, skey, salt, salt_len, argp);
+ va_end (argp);
+}
+
+/**
+ * @brief Derive an IV
+ * @param iv initialization vector
+ * @param skey session key
+ * @param salt salt for the derivation
+ * @param salt_len size of the salt
+ * @param argp pairs of void * & size_t for context chunks, terminated by NULL
+ */
+void
+GNUNET_CRYPTO_aes_derive_iv_v (struct GNUNET_CRYPTO_AesInitializationVector *iv,
+ const struct GNUNET_CRYPTO_AesSessionKey *skey, void *salt,
+ size_t salt_len, va_list argp)
+{
+ GNUNET_CRYPTO_kdf_v (iv->iv, sizeof(iv->iv), salt, salt_len, skey->key,
+ sizeof(skey->key), argp);
+}
+
/* end of crypto_aes.c */
}
+/**
+ * @brief Derive an authentication key
+ * @param key authentication key
+ * @param rkey root key
+ * @param salt salt
+ * @param salt_len size of the salt
+ * @param ... pair of void * & size_t for context chunks, terminated by NULL
+ */
+void
+GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key,
+ const struct GNUNET_CRYPTO_AesSessionKey *rkey,
+ const void *salt,
+ const size_t salt_len,
+ ...)
+{
+ va_list argp;
+
+ va_start (argp, salt_len);
+ GNUNET_CRYPTO_hmac_derive_key_v (key, rkey, salt, salt_len, argp);
+ va_end (argp);
+}
+
+
+/**
+ * @brief Derive an authentication key
+ * @param key authentication key
+ * @param rkey root key
+ * @param salt salt
+ * @param salt_len size of the salt
+ * @param argp pair of void * & size_t for context chunks, terminated by NULL
+ */
+void
+GNUNET_CRYPTO_hmac_derive_key_v(struct GNUNET_CRYPTO_AuthKey *key,
+ const struct GNUNET_CRYPTO_AesSessionKey *rkey,
+ const void *salt,
+ const size_t salt_len,
+ const va_list argp)
+{
+ GNUNET_CRYPTO_kdf_v (key->key, sizeof(key->key), salt, salt_len, rkey->key,
+ sizeof(rkey->key), argp);
+}
+
/**
* Calculate HMAC of a message (RFC 2104)
*
* @param hmac where to store the hmac
*/
void
-GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AesSessionKey *key,
+GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key,
const void *plaintext,
size_t plaintext_len,
GNUNET_HashCode *hmac)
struct sha512_ctx sctx;
memset (&kh, 0, sizeof (kh));
- GNUNET_assert (sizeof (GNUNET_HashCode) > sizeof (struct GNUNET_CRYPTO_AesSessionKey));
- memcpy (&kh, key, sizeof (struct GNUNET_CRYPTO_AesSessionKey));
+ memcpy (&kh, key->key, sizeof (struct GNUNET_CRYPTO_AuthKey));
memset (&ipad, 0x5c, sizeof (ipad));
memset (&opad, 0x36, sizeof (opad));
GNUNET_CRYPTO_hash_xor (&ipad, &kh, &ipad);
--- /dev/null
+/*
+ This file is part of GNUnet.
+ (C) 2010 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file src/util/crypto_kdf.c
+ * @brief Key derivation
+ * @author Nils Durner
+ */
+
+#include <gcrypt.h>
+
+#include "platform.h"
+#include "gnunet_crypto_lib.h"
+
+/**
+ * @brief Derive key
+ * @param result buffer for the derived key, allocated by caller
+ * @param out_len desired length of the derived key
+ * @param xts salt
+ * @param xts_len length of xts
+ * @param skm source key material
+ * @param skm_len length of skm
+ * @param argp va_list of void * & size_t pairs for context chunks
+ * @return GNUNET_YES on success
+ */
+int
+GNUNET_CRYPTO_kdf_v (void *result, const unsigned long long out_len,
+ const void *xts, const size_t xts_len, const void *skm,
+ const size_t skm_len, va_list argp)
+{
+ /*
+ "Finally, we point out to a particularly advantageous instantiation using
+ HMAC-SHA512 as XTR and HMAC-SHA256 in PRF* (in which case the output from SHA-512 is
+ truncated to 256 bits). This makes sense in two ways: First, the extraction part is where we need a
+ stronger hash function due to the unconventional demand from the hash function in the extraction
+ setting. Second, as shown in Section 6, using HMAC with a truncated output as an extractor
+ allows to prove the security of HKDF under considerably weaker assumptions on the underlying
+ hash function."
+
+ http://eprint.iacr.org/2010/264
+ */
+
+ return GNUNET_CRYPTO_hkdf_v (result, out_len, GCRY_MD_SHA512, GCRY_MD_SHA256,
+ xts, xts_len, skm, skm_len, argp);
+}
+
+/**
+ * @brief Derive key
+ * @param result buffer for the derived key, allocated by caller
+ * @param out_len desired length of the derived key
+ * @param xts salt
+ * @param xts_len length of xts
+ * @param skm source key material
+ * @param skm_len length of skm
+ * @param ... void * & size_t pairs for context chunks
+ * @return GNUNET_YES on success
+ */
+int
+GNUNET_CRYPTO_kdf (void *result, const unsigned long long out_len,
+ const void *xts, const size_t xts_len, const void *skm,
+ const size_t skm_len, ...)
+{
+ va_list argp;
+ int ret;
+
+ va_start(argp, skm_len);
+ ret = GNUNET_CRYPTO_kdf_v (result, out_len, xts, xts_len, skm, skm_len, argp);
+ va_end(argp);
+
+ return ret;
+}
sizeof (uint32_t), GCRY_STRONG_RANDOM);
}
while (ret >= ul);
+ return ret % i;
+ }
+ else if (mode == GNUNET_CRYPTO_QUALITY_NONCE)
+ {
+ ul = UINT32_MAX - (UINT32_MAX % i);
+ do
+ {
+ gcry_create_nonce(&ret, sizeof(ret));
+ }
+ while (ret >= ul);
+
return ret % i;
}
else
sizeof (uint64_t), GCRY_STRONG_RANDOM);
}
while (ret >= ul);
+ return ret % max;
+ }
+ else if (mode == GNUNET_CRYPTO_QUALITY_NONCE)
+ {
+ ul = UINT64_MAX - (UINT64_MAX % max);
+ do
+ {
+ gcry_create_nonce(&ret, sizeof(ret));
+ }
+ while (ret >= ul);
+
return ret % max;
}
else