static void mega_aes_key_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { MegaAesKey *aes_key = MEGA_AES_KEY(object); switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); } }
/** * mega_aes_ctr_encryptor_set_mac: * @aes_ctr_encryptor: a #MegaAesCtrEncryptor * @mac: a #MegaChunkedCbcMac calculator * * Add calculator for mac's. */ void mega_aes_ctr_encryptor_set_mac(MegaAesCtrEncryptor* aes_ctr_encryptor, MegaChunkedCbcMac* mac, MegaAesCtrEncryptorDirection dir) { MegaAesCtrEncryptorPrivate* priv; guchar mac_iv[16]; g_return_if_fail(MEGA_IS_AES_CTR_ENCRYPTOR(aes_ctr_encryptor)); g_return_if_fail(MEGA_IS_CHUNKED_CBC_MAC(mac)); g_return_if_fail(aes_ctr_encryptor->priv->key != NULL); priv = aes_ctr_encryptor->priv; priv->direction = dir; g_clear_object(&priv->mac); priv->mac = g_object_ref(mac); // mac iv is nonce + nonce mega_file_key_get_nonce(priv->key, mac_iv); mega_file_key_get_nonce(priv->key, mac_iv + 8); mega_chunked_cbc_mac_setup(mac, MEGA_AES_KEY(priv->key), mac_iv); }
static GConverterResult convert(GConverter *converter, const void *inbuf, gsize inbuf_size, void *outbuf, gsize outbuf_size, GConverterFlags flags, gsize *bytes_read, gsize *bytes_written, GError **error) { MegaAesCtrEncryptor *encryptor = MEGA_AES_CTR_ENCRYPTOR(converter); MegaAesCtrEncryptorPrivate* priv = encryptor->priv; guchar nonce[8]; if (!priv->key || !mega_aes_key_is_loaded(MEGA_AES_KEY(priv->key))) { g_set_error(error, 1, 0, "No key is set for AES-CTR decryption/encryption!"); return G_CONVERTER_ERROR; } if (outbuf_size < inbuf_size) { g_set_error(error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, "No space"); return G_CONVERTER_ERROR; } *bytes_written = *bytes_read = 0; mega_file_key_get_nonce(priv->key, nonce); // if input is not aligned, align it if (inbuf_size > 0 && priv->position % 16 != 0) { gsize offset = priv->position % 16;; gsize to_align = MIN(inbuf_size, 16 - offset); guchar align_buf[16]; if (priv->direction == MEGA_AES_CTR_ENCRYPTOR_DIRECTION_ENCRYPT && priv->mac) mega_chunked_cbc_mac_update(priv->mac, align_buf + offset, to_align); memcpy(align_buf + offset, inbuf, to_align); mega_aes_key_encrypt_ctr(MEGA_AES_KEY(priv->key), nonce, priv->position / 16, align_buf, align_buf, 16); memcpy(outbuf, align_buf + offset, to_align); if (priv->direction == MEGA_AES_CTR_ENCRYPTOR_DIRECTION_DECRYPT) mega_chunked_cbc_mac_update(priv->mac, outbuf, to_align); *bytes_written = *bytes_read = to_align; priv->position += to_align; outbuf += to_align; inbuf += to_align; inbuf_size -= to_align; outbuf_size -= to_align; } // we are aligned, and there are more data on the input if (inbuf_size > 0) { if (priv->direction == MEGA_AES_CTR_ENCRYPTOR_DIRECTION_ENCRYPT && priv->mac) mega_chunked_cbc_mac_update(priv->mac, inbuf, inbuf_size); mega_aes_key_encrypt_ctr(MEGA_AES_KEY(priv->key), nonce, priv->position / 16, inbuf, outbuf, inbuf_size); if (priv->direction == MEGA_AES_CTR_ENCRYPTOR_DIRECTION_DECRYPT && priv->mac) mega_chunked_cbc_mac_update(priv->mac, outbuf, inbuf_size); *bytes_written = *bytes_read = *bytes_read + inbuf_size; priv->position += inbuf_size; } if (flags & G_CONVERTER_INPUT_AT_END) return G_CONVERTER_FINISHED; if (flags & G_CONVERTER_FLUSH) return G_CONVERTER_FLUSHED; return G_CONVERTER_CONVERTED; }