summaryrefslogtreecommitdiff
path: root/lib/sync
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sync')
-rw-r--r--lib/sync/ephy-sync-crypto.c113
1 files changed, 34 insertions, 79 deletions
diff --git a/lib/sync/ephy-sync-crypto.c b/lib/sync/ephy-sync-crypto.c
index 9b17c89ca..629c2ee13 100644
--- a/lib/sync/ephy-sync-crypto.c
+++ b/lib/sync/ephy-sync-crypto.c
@@ -28,8 +28,10 @@
#include <inttypes.h>
#include <json-glib/json-glib.h>
#include <libsoup/soup.h>
-#include <nettle/cbc.h>
#include <nettle/aes.h>
+#include <nettle/cbc.h>
+#include <nettle/hkdf.h>
+#include <nettle/hmac.h>
#include <string.h>
#define HAWK_VERSION 1
@@ -521,84 +523,43 @@ ephy_sync_crypto_concat_bytes (const guint8 *bytes,
return out;
}
-static void
+static guint8 *
ephy_sync_crypto_hkdf (const guint8 *in,
gsize in_len,
- guint8 *salt,
- gsize salt_len,
const guint8 *info,
gsize info_len,
- guint8 *out,
gsize out_len)
{
- char *prk_hex;
- char *tmp_hex;
- guint8 *tmp;
+ struct hmac_sha256_ctx ctx;
+ guint8 *salt;
guint8 *prk;
- guint8 *out_full;
- guint8 *data;
- guint8 counter;
- gsize hash_len;
- gsize data_len;
- gsize n;
+ guint8 *out;
g_assert (in);
g_assert (info);
- g_assert (out);
-
- hash_len = g_checksum_type_get_length (G_CHECKSUM_SHA256);
- g_assert (out_len <= hash_len * 255);
-
- /* Implementation of the HMAC-based Extract-and-Expand Key Derivation Function.
- * See https://tools.ietf.org/html/rfc5869
- */
- /* If salt value was not provided, use an array of hash_len zeros. */
- if (!salt) {
- salt = g_malloc0 (hash_len);
- salt_len = hash_len;
- }
-
- /* Step 1: Extract */
- prk_hex = g_compute_hmac_for_data (G_CHECKSUM_SHA256,
- salt, salt_len,
- in, in_len);
- prk = ephy_sync_utils_decode_hex (prk_hex);
-
- /* Step 2: Expand */
- counter = 1;
- n = (out_len + hash_len - 1) / hash_len;
- out_full = g_malloc (n * hash_len);
-
- for (gsize i = 0; i < n; i++, counter++) {
- if (i == 0) {
- data = ephy_sync_crypto_concat_bytes (info, info_len, &counter, 1, NULL);
- data_len = info_len + 1;
- } else {
- data = ephy_sync_crypto_concat_bytes (out_full + (i - 1) * hash_len, hash_len,
- info, info_len,
- &counter, 1,
- NULL);
- data_len = hash_len + info_len + 1;
- }
-
- tmp_hex = g_compute_hmac_for_data (G_CHECKSUM_SHA256,
- prk, hash_len,
- data, data_len);
- tmp = ephy_sync_utils_decode_hex (tmp_hex);
- memcpy (out_full + i * hash_len, tmp, hash_len);
-
- g_free (data);
- g_free (tmp);
- g_free (tmp_hex);
- }
+ /* Salt is an array of hash length zeros. */
+ salt = g_malloc0 (SHA256_DIGEST_SIZE);
+ prk = g_malloc (SHA256_DIGEST_SIZE);
+ out = g_malloc (out_len);
- memcpy (out, out_full, out_len);
+ hmac_sha256_set_key(&ctx, SHA256_DIGEST_SIZE, salt);
+ hkdf_extract(&ctx,
+ (nettle_hash_update_func*) hmac_sha256_update,
+ (nettle_hash_digest_func*) hmac_sha256_digest,
+ SHA256_DIGEST_SIZE,
+ in_len, in, prk);
+ hmac_sha256_set_key(&ctx, SHA256_DIGEST_SIZE, prk);
+ hkdf_expand(&ctx,
+ (nettle_hash_update_func*) hmac_sha256_update,
+ (nettle_hash_digest_func*) hmac_sha256_digest,
+ SHA256_DIGEST_SIZE,
+ info_len, info, out_len, out);
- g_free (prk_hex);
g_free (salt);
g_free (prk);
- g_free (out_full);
+
+ return out;
}
void
@@ -619,13 +580,11 @@ ephy_sync_crypto_derive_session_token (const char *session_token,
token = ephy_sync_utils_decode_hex (session_token);
info = ephy_sync_crypto_kw ("sessionToken");
- out = g_malloc (3 * len);
/* Use the sessionToken to derive tokenID, reqHMACkey and requestKey. */
- ephy_sync_crypto_hkdf (token, len,
- NULL, 0,
- (guint8 *)info, strlen (info),
- out, 3 * len);
+ out = ephy_sync_crypto_hkdf (token, len,
+ (const guint8 *)info, strlen (info),
+ 3 * len);
*token_id = g_malloc (len);
*req_hmac_key = g_malloc (len);
@@ -663,14 +622,11 @@ ephy_sync_crypto_derive_key_fetch_token (const char *key_fetch_token,
kft = ephy_sync_utils_decode_hex (key_fetch_token);
info_kft = ephy_sync_crypto_kw ("keyFetchToken");
info_keys = ephy_sync_crypto_kw ("account/keys");
- out1 = g_malloc (3 * len);
- out2 = g_malloc (3 * len);
/* Use the keyFetchToken to derive tokenID, reqHMACkey and keyRequestKey. */
- ephy_sync_crypto_hkdf (kft, len,
- NULL, 0,
- (guint8 *)info_kft, strlen (info_kft),
- out1, 3 * len);
+ out1 = ephy_sync_crypto_hkdf (kft, len,
+ (const guint8 *)info_kft, strlen (info_kft),
+ 3 * len);
*token_id = g_malloc (len);
*req_hmac_key = g_malloc (len);
@@ -680,10 +636,9 @@ ephy_sync_crypto_derive_key_fetch_token (const char *key_fetch_token,
memcpy (key_request_key, out1 + 2 * len, len);
/* Use the keyRequestKey to derive respHMACkey and respXORkey. */
- ephy_sync_crypto_hkdf (key_request_key, len,
- NULL, 0,
- (guint8 *)info_keys, strlen (info_keys),
- out2, 3 * len);
+ out2 = ephy_sync_crypto_hkdf (key_request_key, len,
+ (const guint8 *)info_keys, strlen (info_keys),
+ 3 * len);
*resp_hmac_key = g_malloc (len);
*resp_xor_key = g_malloc (2 * len);