summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cesar/cp/cco/action/src/cco_action.c2
-rw-r--r--cesar/cp/cco/action/test/src/secu_stub.c5
-rw-r--r--cesar/cp/secu/inc/pbkdf1.h25
-rw-r--r--cesar/cp/secu/pbkdf1.h15
-rw-r--r--cesar/cp/secu/secu.h23
-rw-r--r--cesar/cp/secu/src/pbkdf1.c101
-rw-r--r--cesar/cp/secu/src/secu.c21
-rw-r--r--cesar/cp/secu/stub/src/secu.c4
-rw-r--r--cesar/cp/secu/test/src/test-aes.c35
-rw-r--r--cesar/cp/sta/action/src/assoc.c3
-rw-r--r--cesar/cp/sta/action/src/sc.c4
11 files changed, 109 insertions, 129 deletions
diff --git a/cesar/cp/cco/action/src/cco_action.c b/cesar/cp/cco/action/src/cco_action.c
index dcbb907229..746b1153e1 100644
--- a/cesar/cp/cco/action/src/cco_action.c
+++ b/cesar/cp/cco/action/src/cco_action.c
@@ -299,7 +299,7 @@ cp_cco_action_gen_nek (cp_t *ctx)
cp_key_t key;
dbg_assert (ctx);
- cp_secu_aes_generate_key (lib_rnd32 (&ctx->rnd), (u8*) &key.key);
+ cp_secu_aes_generate_key (lib_rnd32 (&ctx->rnd), &key);
cp_beacon_change_nek (ctx, 0, key, true /* now. */);
}
diff --git a/cesar/cp/cco/action/test/src/secu_stub.c b/cesar/cp/cco/action/test/src/secu_stub.c
index e631a9b9ad..6e79ee0626 100644
--- a/cesar/cp/cco/action/test/src/secu_stub.c
+++ b/cesar/cp/cco/action/test/src/secu_stub.c
@@ -21,14 +21,13 @@
* \param output the key generated.
*/
void
-cp_secu_aes_generate_key (uint num, u8 *output)
+cp_secu_aes_generate_key (uint num, cp_key_t *output)
{
uint i;
dbg_assert (num);
- dbg_assert (output);
for (i = 0; i < 4; i++)
- ((u32 *) output)[i] = num;
+ output->key[i] = num;
}
enum cp_secu_protocol_run_check_result_t
diff --git a/cesar/cp/secu/inc/pbkdf1.h b/cesar/cp/secu/inc/pbkdf1.h
index 27f144715e..3f8aed4242 100644
--- a/cesar/cp/secu/inc/pbkdf1.h
+++ b/cesar/cp/secu/inc/pbkdf1.h
@@ -15,17 +15,24 @@
*/
/**
- * pbkdf1
- * \param input the input data to hash (can be a clear ascii password)
- * \param input_len length of input
- * \param salt salt to apply to input data
- * \param salt_len length of salt
- * \param it_count iteration number for the hash function
- * \param outputkey the output buffer.
+ * PBKDF1 generation function.
+ * \param input the input data to hash (can be a clear ascii
+ * password).
+ * \param input_length length of input buffer (in bytes).
+ * \param salt salt to apply to input data (can be NULL to use no salt).
+ * \param it_count number of iteration to do.
+ * \param output the output buffer (for the generated key).
+ *
+ * HomePlugAV standard does not follow PKCS#5 V2.0 standard:
+ * - salt must exists (this is not the case for NID generation),
+ * - iteration counter should be at least set to 1000 (this is not the case
+ * for NID generation),
+ * - output length is fixed to CP_SECU_OUTPUT_KEY_SIZE.
*/
void
-secu_pbkdf1 (const u8 input[], uint input_len, u8 salt[],
- uint salt_len, uint it_count, u8 output_key[]);
+secu_pbkdf1 (const u8 input[], const uint input_length,
+ const u8 salt[CP_SECU_SALT_SIZE], const uint it_count,
+ u8 output[CP_SECU_OUTPUT_KEY_SIZE]);
#endif /* cp_secu_inc_pbkdf1_h */
diff --git a/cesar/cp/secu/pbkdf1.h b/cesar/cp/secu/pbkdf1.h
index bb9515a02a..953562c8e5 100644
--- a/cesar/cp/secu/pbkdf1.h
+++ b/cesar/cp/secu/pbkdf1.h
@@ -24,13 +24,16 @@ enum cp_secu_salt_kind_t
typedef enum cp_secu_salt_kind_t cp_secu_salt_kind_t;
/**
- * PBKDF1 functions for the Secu module.
- * \param in the input buffer.
- * \param out the output buffer.
- * \param length the buffer length.
- * \param key key kind.
+ * PBKDF1 generation function.
+ * \param input the input buffer.
+ * \param input_length the length of the input buffer.
+ * \param output the output buffer.
+ * \param output_length the length of the ouput buffer (in bytes). At most
+ * 20 bytes.
+ * \param key_kind the kind of key to generate.
*/
void
-cp_secu_pbkdf1 (const u8 *in, u8 *out, uint length, cp_secu_salt_kind_t key);
+cp_secu_pbkdf1 (const u8 input[], const uint input_length,
+ cp_key_t *output, cp_secu_salt_kind_t key_kind);
#endif /* CP2_SECU_PBKDF1_H_ */
diff --git a/cesar/cp/secu/secu.h b/cesar/cp/secu/secu.h
index 0172a3e1ed..b13b3d219d 100644
--- a/cesar/cp/secu/secu.h
+++ b/cesar/cp/secu/secu.h
@@ -85,12 +85,12 @@ void
cp_secu_protocol_next (cp_secu_protocol_run_t *prun, bool last);
/**
- * Generate the AES key.
+ * Generate an AES key.
* \param num a random number.
- * \param output the key generated.
+ * \param output the generated key.
*/
void
-cp_secu_aes_generate_key (uint num, u8 *output);
+cp_secu_aes_generate_key (uint num, cp_key_t *output_key);
/**
* Generate the NMK from the NPW.
@@ -103,16 +103,9 @@ extern inline cp_key_t
cp_secu_npw2nmk (const u8 *buffer, uint length)
{
cp_key_t keys;
- u8 out[sizeof(cp_key_t)];
dbg_assert (buffer);
- cp_secu_pbkdf1 (buffer, out, length, CP_SECU_SALT_KEY_NMK_HS);
-
- memcpy (&keys.key[0], out, 4);
- memcpy (&keys.key[1], out + 4, 4);
- memcpy (&keys.key[2], out + 8, 4);
- memcpy (&keys.key[3], out + 12, 4);
-
+ cp_secu_pbkdf1 (buffer, length, &keys, CP_SECU_SALT_KEY_NMK_HS);
return keys;
}
@@ -127,15 +120,9 @@ extern inline cp_key_t
cp_secu_dak_gen (const u8 *buffer, uint length)
{
cp_key_t keys;
- u8 out[sizeof(cp_key_t)];
dbg_assert (buffer);
- cp_secu_pbkdf1 (buffer, out, length, CP_SECU_SALT_KEY_DAK);
-
- memcpy (&keys.key[0], out, 4);
- memcpy (&keys.key[1], out + 4, 4);
- memcpy (&keys.key[2], out + 8, 4);
- memcpy (&keys.key[3], out + 12, 4);
+ cp_secu_pbkdf1 (buffer, length, &keys, CP_SECU_SALT_KEY_DAK);
return keys;
}
diff --git a/cesar/cp/secu/src/pbkdf1.c b/cesar/cp/secu/src/pbkdf1.c
index abce6674bd..37f404a2f3 100644
--- a/cesar/cp/secu/src/pbkdf1.c
+++ b/cesar/cp/secu/src/pbkdf1.c
@@ -16,73 +16,60 @@
#include "cp/secu/defs.h"
#include "cp/secu/sha256.h"
+#include "cp/types.h"
#include "cp/secu/pbkdf1.h"
-
#include "cp/secu/inc/pbkdf1.h"
void
-secu_pbkdf1 (const u8 input[], uint input_len, u8 salt[],
- uint salt_len, uint it_count, u8 output_key[])
+secu_pbkdf1 (const u8 input[], const uint input_length,
+ const u8 salt[CP_SECU_SALT_SIZE], const uint it_count,
+ u8 output[CP_SECU_OUTPUT_KEY_SIZE])
{
+ /* Check parameters. */
+ dbg_assert (input);
+ dbg_assert (input_length && input_length <= CP_SECU_PWD_SIZE_MAX);
+ dbg_assert (output);
- u8 dk[68] = "";
+ /* Maximum size of dk. */
+ u8 dk[CP_SECU_PWD_SIZE_MAX + CP_SECU_SALT_SIZE];
u8 sha_output[CP_SECU_SHA256_SIZE];
- uint dp_size, i;
- dbg_assert (input);
- dbg_assert (output_key);
- if (salt_len)
- dbg_assert (salt);
- /*
- * Copy input to DK (max size cannot be greater than DK buffer)
- */
- for (dp_size = 0;
- (dp_size < input_len) && (dp_size < CP_SECU_PWD_SIZE_MAX);
- dp_size++)
- {
- dk[dp_size] = input[dp_size];
- }
- /*
- * Concat salt with input on DK and count total input size
- */
- for (i=0 ; i < salt_len ; i++)
- {
- dk[dp_size+i] = salt[i];
- }
- dp_size += salt_len;
- /*
- * Compute the first derived key with sha256
- */
- cp_secu_sha256 (dk, dp_size, sha_output);
- /*
- * compute the following iterations
- */
- for(i=1 ; i < it_count ; i++)
+ /* Concatenate input and salt. */
+ /* Add input. */
+ memcpy (dk, input, input_length);
+ /* If there is a salt, add it at the end. */
+ if (salt)
+ memcpy (dk + input_length, salt, CP_SECU_SALT_SIZE);
+
+ /* Compute the first derived key with sha256. */
+ cp_secu_sha256 (dk, input_length + (salt ? CP_SECU_SALT_SIZE : 0),
+ sha_output);
+ /* Compute the following iterations. */
+ uint i;
+ for (i = 1; i < it_count; i++)
{
- memcpy (dk, sha_output, CP_SECU_SHA256_SIZE);
- cp_secu_sha256 (dk, CP_SECU_SHA256_SIZE, sha_output);
+ if (i % 2)
+ cp_secu_sha256 (sha_output, CP_SECU_SHA256_SIZE, dk);
+ else
+ cp_secu_sha256 (dk, CP_SECU_SHA256_SIZE, sha_output);
}
- /*
- * we keep only the OutputKeySize leftmost bytes
- */
- memcpy(output_key, sha_output, CP_SECU_OUTPUT_KEY_SIZE);
+ /* Copy only CP_SECU_OUTPUT_KEY_SIZE as result. */
+ memcpy (output, it_count % 2 ? sha_output : dk, CP_SECU_OUTPUT_KEY_SIZE);
}
-/**
- * PBKDF1 functions for the Secu module.
- * \param buffer the input buffer.
- * \param length the buffer length.
- * \param key key kind.
- */
void
-cp_secu_pbkdf1 (const u8 *in, u8 *out, uint length, cp_secu_salt_kind_t key)
+cp_secu_pbkdf1 (const u8 input[], const uint input_length,
+ cp_key_t *output, cp_secu_salt_kind_t key)
{
- u8 salt [8] = {0x08, 0x85, 0x6d, 0xaf, 0x7c, 0xf5, 0x81, 0x00};
+ /* Check parameters. */
+ dbg_assert (input);
+ dbg_assert (input_length);
+ dbg_assert (output);
+ dbg_assert (sizeof (cp_key_t) == CP_SECU_OUTPUT_KEY_SIZE);
- dbg_assert (in);
- dbg_assert (out);
- dbg_assert (key < CP_SECU_SALT_KEY_NB);
+ /* The salt to use for the PBKDF1 function. */
+ u8 salt[CP_SECU_SALT_SIZE] = {0x08, 0x85, 0x6d, 0xaf, 0x7c, 0xf5, 0x81, 0x00};
switch (key)
{
@@ -94,14 +81,16 @@ cp_secu_pbkdf1 (const u8 *in, u8 *out, uint length, cp_secu_salt_kind_t key)
break;
case CP_SECU_SALT_SPIDCOM:
salt[0] += 2;
- salt[4] = 0xA2;
+ salt[4] = 0xA2;
break;
default:
- dbg_assert (false);
+ /* Unsupported value. */
+ dbg_assert_default ();
}
- secu_pbkdf1 (in, length, salt,
- CP_SECU_SALT_SIZE,
- CP_SECU_PBKDF1_ITERATION, out);
+ /* Call the real PBKDF1 function. */
+ secu_pbkdf1 (input, input_length,
+ salt, CP_SECU_PBKDF1_ITERATION,
+ (u8 *) output->key);
}
diff --git a/cesar/cp/secu/src/secu.c b/cesar/cp/secu/src/secu.c
index 39bfd895c3..e9b94a88f8 100644
--- a/cesar/cp/secu/src/secu.c
+++ b/cesar/cp/secu/src/secu.c
@@ -98,18 +98,15 @@ cp_secu_protocol_next (cp_secu_protocol_run_t *prun, bool last)
}
}
-/**
- * Generate the AES key.
- * \param num a random number.
- * \param output the key generated.
- */
void
-cp_secu_aes_generate_key (uint num, u8 *output)
+cp_secu_aes_generate_key (const uint num, cp_key_t *output)
{
- dbg_assert (num);
+ /* Check parameter. */
dbg_assert (output);
- cp_secu_pbkdf1 ((u8*) &num, output, 4, CP_SECU_SALT_SPIDCOM);
+ /* Call the real function to generate an AES key. */
+ cp_secu_pbkdf1 ((const u8 *) &num, sizeof (num),
+ output, CP_SECU_SALT_SPIDCOM);
}
/**
@@ -121,16 +118,12 @@ cp_secu_aes_generate_key (uint num, u8 *output)
cp_nid_t
cp_secu_nmk2nid(cp_key_t nmk, u8 security_level)
{
- uint i;
cp_nid_t nid = 0;
- u8 buffer[CP_NMK_SIZE];
+ u8 buffer[CP_SECU_OUTPUT_KEY_SIZE];
dbg_assert (security_level <= 2);
- for (i = 0; i < 4; i++)
- memcpy (buffer + i * 4, &nmk.key[i], 4);
-
- secu_pbkdf1 (buffer, CP_NMK_SIZE, NULL, 0, CP_SECU_PBKDF1_ITERATION_NID,
+ secu_pbkdf1 ((const u8 *) &nmk, sizeof (nmk), NULL, CP_SECU_PBKDF1_ITERATION_NID,
buffer);
/* Set the right nibble of rightmost octet of NID = rightmost nibble
diff --git a/cesar/cp/secu/stub/src/secu.c b/cesar/cp/secu/stub/src/secu.c
index 1f6e6fcbe1..750aee7a58 100644
--- a/cesar/cp/secu/stub/src/secu.c
+++ b/cesar/cp/secu/stub/src/secu.c
@@ -27,7 +27,7 @@ void
cp_secu_protocol_next (cp_secu_protocol_run_t *prun, bool last) __attribute__((weak));
void
-cp_secu_aes_generate_key (uint num, u8 *output) __attribute__((weak));
+cp_secu_aes_generate_key (uint num, cp_key_t *output) __attribute__((weak));
cp_nid_t
cp_secu_nmk2nid(cp_key_t nmk, u8 security_level) __attribute__((weak));
@@ -47,7 +47,7 @@ void
cp_secu_protocol_next (cp_secu_protocol_run_t *prun, bool last) {}
void
-cp_secu_aes_generate_key (uint num, u8 *output) {}
+cp_secu_aes_generate_key (uint num, cp_key_t *output) {}
cp_nid_t
cp_secu_nmk2nid(cp_key_t nmk, u8 security_level)
diff --git a/cesar/cp/secu/test/src/test-aes.c b/cesar/cp/secu/test/src/test-aes.c
index 1e205cf57a..b8ddfdea02 100644
--- a/cesar/cp/secu/test/src/test-aes.c
+++ b/cesar/cp/secu/test/src/test-aes.c
@@ -18,6 +18,7 @@
#include "string.h"
#include "cp/secu/aes.h"
+#include "cp/secu/secu.h"
#include "cp/types.h"
void
@@ -25,26 +26,26 @@ test_case_aes (test_t test)
{
aes_context aes;
- u32 key[4] = {0x03020100, 0x08070605, 0x0D0C0B0A, 0x1211100F};
+ cp_key_t key = { {0x03020100, 0x08070605, 0x0D0C0B0A, 0x1211100F} };
- u32 input [4] = {0xA4126850, 0x89C8085F, 0x80597FB9, 0x59838B03};
+ cp_key_t input = { {0xA4126850, 0x89C8085F, 0x80597FB9, 0x59838B03} };
- u32 result [4] = {0x5332F5D8, 0x7DEF8982, 0xA406B506, 0xC9E95BFD};
+ cp_key_t result = { {0x5332F5D8, 0x7DEF8982, 0xA406B506, 0xC9E95BFD} };
- u32 output [4];
+ cp_key_t output;
- aes_set_key (&aes, (u8*) key);
- aes_encrypt (&aes, (u8*) input, (u8*) output);
+ aes_set_key (&aes, (u8*) &key.key);
+ aes_encrypt (&aes, (u8*) &input.key, (u8*) &output.key);
test_case_begin (test, "AES");
test_begin (test, "Verify")
{
- test_fail_if (memcmp(output, result, 16) != 0,
+ test_fail_if (memcmp((u8 *) &output.key, (u8 *) &result.key, 16) != 0,
"Wrong encryption");
- aes_decrypt (&aes, (u8*) output, (u8*) output);
- test_fail_if (memcmp(output, input, 16) != 0,
+ aes_decrypt (&aes, (u8*) &output.key, (u8*) &output.key);
+ test_fail_if (memcmp((u8 *) &output.key, (u8 *) &input.key, 16) != 0,
"Wrong encryption");
}
test_end;
@@ -119,19 +120,19 @@ test_case_aes_gen_key (test_t test)
test_begin (test, "AES")
{
- u8 output [16];
- cp_key_t key;
+ cp_key_t output = {{ 0x1, 0x2, 0x3, 0x4 }};
+ cp_key_t key = {{ 0xFF42, 0x42FF, 0x4FF2, 0xF42F }};
- cp_secu_aes_generate_key (0x12345, output);
- cp_secu_aes_generate_key (0x12345, (u8*) &key.key);
+ cp_secu_aes_generate_key (0x12345, &output);
+ cp_secu_aes_generate_key (0x12345, &key);
- test_fail_unless (bitstream_direct_read (output, 0, 32) ==
+ test_fail_unless (bitstream_direct_read (output.key, 0, 32) ==
key.key[0]);
- test_fail_unless (bitstream_direct_read (output, 32, 32) ==
+ test_fail_unless (bitstream_direct_read (output.key, 32, 32) ==
key.key[1]);
- test_fail_unless (bitstream_direct_read (output, 64, 32) ==
+ test_fail_unless (bitstream_direct_read (output.key, 64, 32) ==
key.key[2]);
- test_fail_unless (bitstream_direct_read (output, 96, 32) ==
+ test_fail_unless (bitstream_direct_read (output.key, 96, 32) ==
key.key[3]);
}
test_end;
diff --git a/cesar/cp/sta/action/src/assoc.c b/cesar/cp/sta/action/src/assoc.c
index 768b62cea3..92c1be49b9 100644
--- a/cesar/cp/sta/action/src/assoc.c
+++ b/cesar/cp/sta/action/src/assoc.c
@@ -388,7 +388,8 @@ cp_sta_action_assoc__sc_associated__cm_get_key_req_pid_3 (cp_t *ctx,
cnf.key_type = CP_MSG_KEY_HASH_KEY;
cnf.nid = cp_sta_own_data_get_nid (ctx);
cnf.eks = CP_MME_PEKS_TEK_MIN;
- cp_secu_aes_generate_key (lib_rnd32 (&ctx->rnd), cnf.hash_key);
+ /* TODO: generate an hash key.
+ cp_secu_aes_generate_key (lib_rnd32 (&ctx->rnd), cnf.hash_key); */
/* Generate TEK with hash key from CM_HET_KEY REQ and CNF. */
cp_secu_tek_gen ((u32 *)req.hash_key, (u32 *)cnf.hash_key,
&ctx->sta_action.sc.tek);
diff --git a/cesar/cp/sta/action/src/sc.c b/cesar/cp/sta/action/src/sc.c
index 8225eb4368..41b5ccb6d5 100644
--- a/cesar/cp/sta/action/src/sc.c
+++ b/cesar/cp/sta/action/src/sc.c
@@ -277,8 +277,8 @@ cp_sta_action_sc__sc_wait_peer_associated__new_sta_associated (cp_t *ctx,
req.relayed = false;
req.key_type = CP_MSG_KEY_HASH_KEY;
req.nid = cp_sta_own_data_get_nid (ctx);
- /* Generate hash key. */
- cp_secu_aes_generate_key (lib_rnd32 (&ctx->rnd), req.hash_key);
+ /* TODO: Generate hash key.
+ cp_secu_aes_generate_key (lib_rnd32 (&ctx->rnd), req.hash_key); */
/* Keep a copy of the hash key. */
memcpy (ctx->sta_action.sc.hash_key, req.hash_key, CP_HASH_KEY_SIZE);
cp_secu_protocol_run_new (&ctx->sta_action.sc.prun, 3,