diff options
author | jpadkins <jacobpadkins@gmail.com> | 2017-06-14 02:32:52 +0300 |
---|---|---|
committer | jpadkins <jacobpadkins@gmail.com> | 2017-06-14 03:08:52 +0300 |
commit | d19064af6b8f44a16fbf79e5ca8dff8fbe895897 (patch) | |
tree | 5c82c83482f3504fb3a8f0d083acfdd30ebab7a8 | |
parent | 78c51cdc55fcf4bcb6e0323b64b978cb59ec13b4 (diff) |
Updated part_encrypt and part_decrypt.
-rw-r--r-- | check/magma/prime/prime_check.c | 116 | ||||
-rw-r--r-- | src/core/strings/length.c | 2 | ||||
-rw-r--r-- | src/providers/prime/messages/chunks/encrypted.c | 9 | ||||
-rw-r--r-- | src/providers/prime/messages/messages.c | 162 | ||||
-rw-r--r-- | src/providers/prime/prime.h | 3 |
5 files changed, 112 insertions, 180 deletions
diff --git a/check/magma/prime/prime_check.c b/check/magma/prime/prime_check.c index 8f963823..2c03bf98 100644 --- a/check/magma/prime/prime_check.c +++ b/check/magma/prime/prime_check.c @@ -422,113 +422,44 @@ START_TEST (check_prime_chunk_spanning_s) { //log_disable(); log_enable(); bool_t outcome = true; - prime_encrypted_chunk_t *chunk = NULL; - prime_chunk_keys_t encrypt_keys, decrypt_keys; - ed25519_key_t *signing_pub = NULL, *signing_priv = NULL; - prime_chunk_keks_t *encrypt_keks = NULL, *decrypt_keks = NULL; - stringer_t *errmsg = MANAGEDBUF(1024), *data = NULL, *set = NULL; - secp256k1_key_t *encryption_pub = NULL, *encryption_priv = NULL, *recipient_pub = NULL, *recipient_priv = NULL; + stringer_t *raw = NULL, *message = NULL, *rebuilt = NULL, *errmsg = MANAGEDBUF(1024); + prime_t *destination = NULL, *org = NULL, *recipient = NULL, *request = NULL, *signet = NULL; if (status()) { - // We add spaces between the categories to increase the number of randomly placed whitespace. - data = rand_choices("0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ " \ - "+!@#$%^&*()_|\"?><{}>~`<[]/.,;'\\-=\n\t", 1024, MANAGEDBUF(1024)); - - if (!(signing_priv = ed25519_generate()) || !(encryption_priv = secp256k1_generate()) || !(recipient_priv = secp256k1_generate()) || - !(signing_pub = ed25519_public_set(ed25519_public_get(signing_priv, MANAGEDBUF(32)))) || - !(encryption_pub = secp256k1_public_set(secp256k1_public_get(encryption_priv, MANAGEDBUF(33)))) || - !(recipient_pub = secp256k1_public_set(secp256k1_public_get(recipient_priv, MANAGEDBUF(33))))) { - st_sprint(errmsg, "Key generation failed."); + if (!(destination = prime_key_generate(PRIME_ORG_KEY, NONE)) || !(org = prime_signet_generate(destination)) || + !(recipient = prime_key_generate(PRIME_USER_KEY, NONE)) || !(request = prime_request_generate(recipient, NULL)) || + !(signet = prime_request_sign(request, destination))) { + st_sprint(errmsg, "PRIME message test identity generation failed."); outcome = false; } - - mm_wipe(&encrypt_keys, sizeof(prime_chunk_keys_t)); - mm_wipe(&decrypt_keys, sizeof(prime_chunk_keys_t)); - - encrypt_keys.signing = signing_priv; - encrypt_keys.encryption = encryption_priv; - encrypt_keys.recipient = recipient_pub; - - decrypt_keys.signing = signing_pub; - decrypt_keys.encryption = encryption_pub; - decrypt_keys.recipient = recipient_priv; - - if (outcome && (!(encrypt_keks = keks_get(&encrypt_keys, NULL)) || !(decrypt_keks = keks_set(&decrypt_keys, NULL)) || - st_cmp_cs_eq(encrypt_keks->recipient, decrypt_keks->recipient))) { - st_sprint(errmsg, "Encrypted chunk kek creation failed."); + // Generate a large (> 16mb) random buffer for the message body. + else if (!(raw = rand_choices("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 20971520, NULL))) { + st_sprint(errmsg, "Unable to generate random message."); outcome = false; } - - // Test chunk creation using an ephemeral signing/encryption key, and a recipient public key. - else if (outcome && !(chunk = encrypted_chunk_set(PRIME_CHUNK_COMMON, signing_priv, encrypt_keks, data, 0))) { - st_sprint(errmsg, "Encrypted chunk creation failed."); + else if (!(message = prime_message_encrypt(raw, NULL, NULL, destination, signet))) { + st_sprint(errmsg, "PRIME message encryption test failed."); outcome = false; } - else if (outcome && !(set = encrypted_chunk_get(signing_pub, decrypt_keks, encrypted_chunk_buffer(chunk), MANAGEDBUF(1024)))) { - st_sprint(errmsg, "Encrypted chunk parsing failed."); + else if (!(rebuilt = prime_message_decrypt(message, org, recipient))) { + st_sprint(errmsg, "PRIME message decryption test failed."); outcome = false; } - else if (outcome && st_cmp_cs_eq(data, set)) { - st_sprint(errmsg, "Encrypted chunk comparison failed. The output isn't identical to the input."); + else if (st_cmp_cs_eq(raw, rebuilt)) { + st_sprint(errmsg, "PRIME message encryption before and after comparison test failed."); outcome = false; } - // Cleanup and reset the pointers so we don't trigger a double free. - encrypted_chunk_cleanup(chunk); - chunk = NULL; - - // Randomize the test data. - data = rand_choices("0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ " \ - "+!@#$%^&*()_|\"?><{}>~`<[]/.,;'\\-=\n\t", 1024, MANAGEDBUF(1024)); + st_cleanup(message, rebuilt, raw); + raw = rebuilt = message; - if (outcome && !(chunk = encrypted_chunk_set(PRIME_CHUNK_HEADERS, signing_priv, encrypt_keks, data, 0))) { - st_sprint(errmsg, "Encrypted chunk creation failed."); - outcome = false; - } - else if (outcome && !(set = encrypted_chunk_get(signing_pub, decrypt_keks, encrypted_chunk_buffer(chunk), MANAGEDBUF(1024)))) { - st_sprint(errmsg, "Encrypted chunk parsing failed."); - outcome = false; - } - else if (outcome && st_cmp_cs_eq(data, set)) { - st_sprint(errmsg, "Encrypted chunk comparison failed. The output isn't identical to the input."); - outcome = false; - } - - // Cleanup and reset the pointers so we don't trigger a double free. - encrypted_chunk_cleanup(chunk); - chunk = NULL; - - - // Randomize the test data. - data = rand_choices("0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ " \ - "+!@#$%^&*()_|\"?><{}>~`<[]/.,;'\\-=\n\t", 1024, MANAGEDBUF(1024)); - - if (outcome && !(chunk = encrypted_chunk_set(PRIME_CHUNK_BODY, signing_priv, encrypt_keks, data, 0))) { - st_sprint(errmsg, "Encrypted chunk creation failed."); - outcome = false; - } - else if (outcome && !(set = encrypted_chunk_get(signing_pub, decrypt_keks, encrypted_chunk_buffer(chunk), MANAGEDBUF(1024)))) { - st_sprint(errmsg, "Encrypted chunk parsing failed."); - outcome = false; - } - else if (outcome && st_cmp_cs_eq(data, set)) { - st_sprint(errmsg, "Encrypted chunk comparison failed. The output isn't identical to the input."); - outcome = false; - } - - // Cleanup and reset the pointers so we don't trigger a double free. - encrypted_chunk_cleanup(chunk); - chunk = NULL; + prime_cleanup(destination); + prime_cleanup(recipient); + prime_cleanup(request); + prime_cleanup(signet); + prime_cleanup(org); - keks_cleanup(encrypt_keks); - keks_cleanup(decrypt_keks); - if (signing_pub) ed25519_free(signing_pub); - if (signing_priv) ed25519_free(signing_priv); - if (recipient_pub) secp256k1_free(recipient_pub); - if (recipient_priv) secp256k1_free(recipient_priv); - if (encryption_pub) secp256k1_free(encryption_pub); - if (encryption_priv) secp256k1_free(encryption_priv); } log_test("PRIME / CHUNKS / SPANNING / SINGLE THREADED:", errmsg); @@ -538,7 +469,8 @@ END_TEST START_TEST (check_prime_message_naked_s) { - log_disable(); + //log_disable(); + log_enable(); bool_t result = true; uint32_t max = check_message_max(); stringer_t *raw = NULL, *message = NULL, *rebuilt = NULL, *errmsg = MANAGEDBUF(1024); diff --git a/src/core/strings/length.c b/src/core/strings/length.c index 9d98ae89..81c76361 100644 --- a/src/core/strings/length.c +++ b/src/core/strings/length.c @@ -15,8 +15,8 @@ size_t st_length_get(stringer_t *s) { char *data; + uint32_t opts; size_t result = 0; - uint32_t opts; ; if (!s || !(opts = *((uint32_t *)s))) { return 0; diff --git a/src/providers/prime/messages/chunks/encrypted.c b/src/providers/prime/messages/chunks/encrypted.c index 186834f9..5d5a300f 100644 --- a/src/providers/prime/messages/chunks/encrypted.c +++ b/src/providers/prime/messages/chunks/encrypted.c @@ -15,6 +15,7 @@ void encrypted_chunk_free(prime_encrypted_chunk_t *chunk) { if (chunk->trailing) st_free(chunk->trailing); if (chunk->encrypted) st_free(chunk->encrypted); if (chunk->signature) st_free(chunk->signature); + if (chunk->next) encrypted_chunk_free(chunk->next); mm_free(chunk); } @@ -57,6 +58,13 @@ stringer_t * encrypted_chunk_buffer(prime_encrypted_chunk_t *chunk) { buffer = chunk->encrypted; } + // If the *next pointer is set then this is part of a series of + // spanning chunks. + while (chunk->next) { + buffer = st_append(buffer, chunk->next); + chunk = chunk->next; + } + return buffer; } @@ -160,6 +168,7 @@ prime_encrypted_chunk_t * encrypted_chunk_set(prime_message_chunk_type_t type, e return result; } +// Decrypt stringer_t * encrypted_chunk_get(ed25519_key_t *signing, prime_chunk_keks_t *keks, stringer_t *chunk, stringer_t *output) { int32_t payload_size = 0; diff --git a/src/providers/prime/messages/messages.c b/src/providers/prime/messages/messages.c index c22b850f..10441e03 100644 --- a/src/providers/prime/messages/messages.c +++ b/src/providers/prime/messages/messages.c @@ -69,70 +69,29 @@ prime_message_t * encrypted_message_alloc(void) { return result; } -/* @brief Get a message part as binary data. +/* @brief Get the part as an encrypted data buffer. * - * @param data a stringer_t * pointing to the message data. - * @param remaining a uint32_t holding the length of the remaining message data. - * @param keys the prime_chunk_keys_t for the message. - * @param keks the prime_chunk_keks_t for the message. - * @param type a uint32_t holding the expected chunk type flag. - * - * @return a stringer_t * pointing to the total concatenated binary data of every - * chunk representing the part. + * @param payload + * @param type + * @param keks + * @param signing * + * @return */ -/* -stringer_t * part_get(stringer_t *data, size_t remaining, prime_chunk_keys_t *keys, prime_chunk_keks_t *keks, uint32_t type) { +prime_encrypted_chunk_t * part_encrypt(stringer_t *payload, uint8_t type, prime_chunk_keks_t *keks, ed25519_key_t *signing) { - stringer_t *part = NULL; - placer_t chunk = pl_null(); - uint32_t read_type = 0, total_size = 0, chunk_payload_size = 0, chunk_slot_size = 0; + size_t num_chunks = 0; + stringer_t *slice = NULL; + prime_encrypted_chunk_t *chunk = NULL, *prev = NULL, *curr = NULL; - if (chunk_header_read(PLACER(data, remaining), &read_type, &total_size, &chunk) < 0 || read_type != type) { + if (!(slice = PLACER(st_data_get(payload), st_length_get(payload))) || + !(num_chunks = (st_length_get(payload) / 16777098) + 1)) { return NULL; } - // If the size > 16777332, this part consists of multiple spanning chunks. - if (size > 16777332) { - - // Parse the payload size. - if ((chunk_payload_size = chunk_header_size(chunk)) == -1) { - log_pedantic("Invalid chunk size. { size = -1 }"); - return NULL; - } - - // Parse the keyslot size. - else if ((chunk_slot_size = (slots_count(type) * SECP256K1_SHARED_SECRET_LEN)) == 0) { - log_pedantic("Invalid keyslot size. { size = %zu }", slot_size); - return NULL; - } - - // Set the chunk placer. - chunk - - // Append the raw chunk data. - part = st_append(part, encrypted_chunk_set(keys.signing, keks, &chunk, NULL)); - - chunk_payload_size = chunk_slot_size = 0; - } - - - return part; -} -*/ - -// Get the part as an encrypted data buffer. -stringer_t * part_encrypt(stringer_t *payload, uint8_t type, prime_chunk_keks_t *keks, ed25519_key_t *signing) { - - size_t num_chunks = 0; - prime_encrypted_chunk_t *chunk; - stringer_t *result = NULL, *slice = NULL; - // Create a stringer with a serialized set of encrypted chunks. If necessary the payload is split into multiple chunks. - // Pass this into encrypted_chunk_get() each portion of the payload. Note you'll need to tell the set that it's a span, or have the chunk get do the splitting. - // Return the serialized encrypted_chunk_get() values buffer, combining as necessary. - - num_chunks = (st_length_get(payload) / 16777098) + 1; + // Pass this into encrypted_chunk_get() each portion of the payload. Note you'll need to tell the set that it's a span, + // or have the chunk get do the splitting.Return the serialized encrypted_chunk_get() values buffer, combining as necessary. for (size_t i = 0; i < num_chunks; i++) { @@ -141,54 +100,77 @@ stringer_t * part_encrypt(stringer_t *payload, uint8_t type, prime_chunk_keks_t st_data_set(slice, st_data_get(payload) + (16777098 * i)); // Process the chunk stringer into an encrypted chunk. - if (!(chunk = encrypted_chunk_set(type, signing, keks, slice, ((i + i < num_chunks) ? true : false)))) { - st_cleanup(result); + if (!(curr = encrypted_chunk_set(type, signing, keks, slice, ((i + i < num_chunks) ? 128 : 0)))) { + encrypted_chunk_cleanup(chunk); return NULL; } - // Either append the chunk data to result, or set result to the chunk data if this is the first chunk. - result = (result) ? st_append(result, encrypted_chunk_buffer(chunk)) : st_dupe(encrypted_chunk_buffer(chunk)); - - encrypted_chunk_cleanup(chunk); + if (!chunk) { + chunk = curr; + prev = curr; + curr = NULL; + } + else { + prev->next = curr; + prev = curr; + curr = NULL; + } } - return result; + return chunk; } -// TODO: Set needs to have in input parameter that may be set to the length of the encrypted data remaining in the message buffer. -// Get the part as a decrypted data buffer. -stringer_t * part_decrypt(stringer_t *payload, prime_chunk_keks_t *keks, ed25519_key_t *signing) { +/* @brief Get the part as a decrypted data buffer. + * + * @param payload + * @param part + * @param keks + * @param signing + * @param type + * + * @return + */ +stringer_t * part_decrypt(stringer_t *payload, stringer_t *part, prime_chunk_keks_t *keks, ed25519_key_t *signing, uint8_t type) { - uint8_t type; - uint32_t remaining, size; + size_t part_size; + uint8_t curr_type; + uint32_t chunk_size = 0; placer_t slice = pl_null(); - stringer_t *result = NULL, *chunk = NULL; + stringer_t *result = NULL, *curr_chunk = NULL; + + // Set the data buffer of the part stringer to the beginning of the payload. + st_data_set(part, st_data_get(payload)); - // Set remaining to the length of payload. - remaining = st_length_get(payload); + while (true) { - while (remaining) { + // Read the chunk headers from the beginning of the remaining payload. + if (chunk_header_read(payload, &curr_type, &chunk_size, &slice) != 0) break; + part_size += st_length_get(&slice); - // Read the chunk headers from the beginning of the payload. - chunk_header_read(payload, &type, &size, &slice); + // TODO: Instead, check if the spanning-chunk flag (128) is set in the header. + // Check if the chunk is still a part of the part that we are decrypting. + if (curr_type != type) break; - // Pass this into encrypted_chunk_get() and either set the result buffer to the return value or - // append the return value to the result buffer. - if (!(chunk = encrypted_chunk_get(signing, keks, &slice, NULL))) { + // Pass this into encrypted_chunk_get(). + if (!(curr_chunk = encrypted_chunk_get(signing, keks, &slice, NULL))) { st_cleanup(result); return NULL; } - result = (result) ? st_append(result, chunk) : st_dupe(chunk); + // Either append curr_chunk onto result or set result equal to chunk. + result = st_append(result, curr_chunk); - // Decrement remaining by the length of the constructed chunk. - remaining -= pl_length_get(slice); + // Free curr_chunk. + st_free(curr_chunk); // Update payload and loop if necessary. - st_data_set(payload, st_data_get(payload) + pl_length_get(slice)); - st_length_set(payload, remaining); + st_data_set(payload, st_data_get(payload) + st_length_get(&slice)); + st_length_set(payload, st_length_get(payload) - st_length_get(&slice)); } + // Construct the part-spanning chunk placer. + st_length_set(part, part_size); + return result; } @@ -265,8 +247,10 @@ stringer_t * naked_message_get(stringer_t *message, prime_org_signet_t *org, pri data += st_length_get(&chunk[2]); remaining -= st_length_get(&chunk[2]); - if (chunk_header_read(PLACER(data, remaining), &type, &size, &chunk[3]) < 0 || type != PRIME_CHUNK_BODY || - !(body = part_encrypt(&chunk[3], PRIME_CHUNK_BODY, keks, keys.signing))) { + //(void)body_size; + if (//chunk_header_read(PLACER(data, remaining), &type, &size, &chunk[3]) < 0 || type != PRIME_CHUNK_BODY || + !(body = part_decrypt(PLACER(data, remaining), &chunk[3], keks, keys.signing, PRIME_CHUNK_BODY))) { + //!(body = encrypted_chunk_get(keys.signing, keks, &chunk[3], NULL))) { ephemeral_chunk_cleanup(ephemeral); st_free(headers); keks_free(keks); @@ -274,8 +258,12 @@ stringer_t * naked_message_get(stringer_t *message, prime_org_signet_t *org, pri } // Tree signature. + // 191892 data += st_length_get(&chunk[3]); remaining -= st_length_get(&chunk[3]); + // 191824 + //data += body_size; + //remaining -= body_size; if (chunk_header_read(PLACER(data, remaining), &type, &size, &chunk[4]) < 0 || type != PRIME_SIGNATURE_TREE || !(tree = signature_tree_alloc())) { @@ -411,10 +399,14 @@ prime_message_t * naked_message_set(stringer_t *message, prime_org_key_t *destin encrypted_message_free(result); return NULL; } - else if (!(result->content.body = part_decrypt(&body, &(result->keks), result->keys.signing))) { + else if (!(result->content.body = part_encrypt(&body, PRIME_CHUNK_BODY, &(result->keks), result->keys.signing))) { encrypted_message_free(result); return NULL; } + /*else if (!(result->content.body = encrypted_chunk_set(PRIME_CHUNK_BODY, result->keys.signing, &(result->keks), &body, 0))) { + encrypted_message_free(result); + return NULL; + }*/ // Generate the signatures. if (!(tree = signature_tree_alloc())) { @@ -427,8 +419,6 @@ prime_message_t * naked_message_set(stringer_t *message, prime_org_key_t *destin signature_tree_add(tree, encrypted_chunk_buffer(result->metadata.headers)); signature_tree_add(tree, encrypted_chunk_buffer(result->content.body)); - // TODO: - // Calculate the tree signature. result->signatures.tree = signature_tree_get(result->keys.signing, tree, &(result->keks)); signature_tree_free(tree); diff --git a/src/providers/prime/prime.h b/src/providers/prime/prime.h index 5f5bc903..ac97c4fc 100644 --- a/src/providers/prime/prime.h +++ b/src/providers/prime/prime.h @@ -260,7 +260,7 @@ typedef struct __attribute__ ((packed)) { /** * @typedef prime_encrypted_chunk_t */ -typedef struct __attribute__ ((packed)) { +typedef struct __attribute__ ((packed)) prime_encrypted_chunk_t { struct { uint8_t type; /**< Chunk type, 1 through 255. >*/ uint32_t length; /**< Payload length, must be divisible by 16 and less than 2^24 - 1. >*/ @@ -274,6 +274,7 @@ typedef struct __attribute__ ((packed)) { stringer_t *trailing; stringer_t *encrypted; prime_chunk_slots_t *slots; + struct prime_encrypted_chunk_t *next; } prime_encrypted_chunk_t; |