Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/lavabit/magma.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjpadkins <jacobpadkins@gmail.com>2017-06-14 02:32:52 +0300
committerjpadkins <jacobpadkins@gmail.com>2017-06-14 03:08:52 +0300
commitd19064af6b8f44a16fbf79e5ca8dff8fbe895897 (patch)
tree5c82c83482f3504fb3a8f0d083acfdd30ebab7a8
parent78c51cdc55fcf4bcb6e0323b64b978cb59ec13b4 (diff)
Updated part_encrypt and part_decrypt.
-rw-r--r--check/magma/prime/prime_check.c116
-rw-r--r--src/core/strings/length.c2
-rw-r--r--src/providers/prime/messages/chunks/encrypted.c9
-rw-r--r--src/providers/prime/messages/messages.c162
-rw-r--r--src/providers/prime/prime.h3
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;