Fix DM CCM length setup and separate media nonces
This commit is contained in:
1 parent
ce5f5bb7d0
commit
67bbf80769
2 files changed
+30
-4
No files matched your search
+25
-4
@@ -14,6 +14,19 @@
|
||||
|
||||
#define DM_ID "dm_crypto"
|
||||
|
||||
/* Медиа использует тот же ключ target, но отдельное пространство nonce. */
|
||||
void dm_build_media_nonce(uint64_t author, const uint8_t media_id[16], uint64_t part, uint8_t nonce[DM_NONCE_SIZE]) {
|
||||
SHA256_CTX ctx;
|
||||
uint8_t hash[32];
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx, "utun_dm_media", 13);
|
||||
SHA256_Update(&ctx, &author, sizeof(author));
|
||||
SHA256_Update(&ctx, media_id, 16);
|
||||
SHA256_Update(&ctx, &part, sizeof(part));
|
||||
SHA256_Final(hash, &ctx);
|
||||
memcpy(nonce, hash, DM_NONCE_SIZE);
|
||||
}
|
||||
|
||||
uint64_t dm_derive_conv_id(uint64_t a, uint64_t b) {
|
||||
uint64_t lo = a < b ? a : b;
|
||||
uint64_t hi = a < b ? b : a;
|
||||
@@ -80,10 +93,17 @@ void dm_build_nonce(uint64_t conv_id, uint64_t author, uint64_t seq, uint8_t non
|
||||
static int dm_ccm_crypt(const uint8_t key[DM_CONTENT_KEY_SIZE], const uint8_t nonce[DM_NONCE_SIZE],
|
||||
const uint8_t* in, size_t in_len, uint8_t* out, size_t* out_len,
|
||||
int encrypt, const uint8_t* tag_in) {
|
||||
if (!key || !nonce || !in || !out || !out_len) return -1;
|
||||
if (!key || !nonce || (!in && in_len) || !out || !out_len ||
|
||||
(encrypt ? in_len > DM_CCM_PLAIN_MAX : in_len < DM_TAG_SIZE || in_len - DM_TAG_SIZE > DM_CCM_PLAIN_MAX)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_DM, "%s: invalid CCM arguments encrypt=%d bytes=%zu", DM_ID, encrypt, in_len);
|
||||
return -1;
|
||||
}
|
||||
*out_len = 0;
|
||||
static const uint8_t empty = 0;
|
||||
if (!in) in = ∅
|
||||
|
||||
EVP_CIPHER_CTX* ectx = EVP_CIPHER_CTX_new();
|
||||
if (!ectx) return -1;
|
||||
if (!ectx) { DEBUG_ERROR(DEBUG_CATEGORY_DM, "%s: CCM context allocation failed", DM_ID); return -1; }
|
||||
const EVP_CIPHER* cipher = EVP_aes_256_ccm();
|
||||
|
||||
int rc = -1;
|
||||
@@ -93,6 +113,7 @@ static int dm_ccm_crypt(const uint8_t key[DM_CONTENT_KEY_SIZE], const uint8_t no
|
||||
|| EVP_CIPHER_CTX_ctrl(ectx, EVP_CTRL_AEAD_SET_TAG, DM_TAG_SIZE, NULL) != 1
|
||||
|| EVP_EncryptInit_ex(ectx, NULL, NULL, key, nonce) != 1) goto done;
|
||||
int outl;
|
||||
if (EVP_EncryptUpdate(ectx, NULL, &outl, NULL, (int)in_len) != 1) goto done;
|
||||
if (EVP_EncryptUpdate(ectx, out, &outl, in, (int)in_len) != 1 || outl != (int)in_len) goto done;
|
||||
int tmpl;
|
||||
if (EVP_EncryptFinal_ex(ectx, out + outl, &tmpl) != 1) goto done;
|
||||
@@ -106,14 +127,14 @@ static int dm_ccm_crypt(const uint8_t key[DM_CONTENT_KEY_SIZE], const uint8_t no
|
||||
|| EVP_CIPHER_CTX_ctrl(ectx, EVP_CTRL_AEAD_SET_TAG, DM_TAG_SIZE, (void*)(tag_in ? tag_in : in + body)) != 1
|
||||
|| EVP_DecryptInit_ex(ectx, NULL, NULL, key, nonce) != 1) goto done;
|
||||
int outl;
|
||||
if (EVP_DecryptUpdate(ectx, NULL, &outl, NULL, (int)body) != 1) goto done;
|
||||
if (EVP_DecryptUpdate(ectx, out, &outl, in, (int)body) != 1 || outl != (int)body) goto done;
|
||||
int tmpl;
|
||||
if (EVP_DecryptFinal_ex(ectx, out + outl, &tmpl) != 1) goto done;
|
||||
*out_len = body;
|
||||
}
|
||||
rc = 0;
|
||||
done:
|
||||
EVP_CIPHER_CTX_free(ectx);
|
||||
if (rc) DEBUG_ERROR(DEBUG_CATEGORY_DM, "%s: CCM %s failed bytes=%zu", DM_ID, encrypt ? "encrypt" : "decrypt", in_len);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user