mirror of
https://github.com/morgan9e/UxPlay
synced 2026-04-14 00:04:13 +09:00
restore RPiPlay's crypto implementation, now they have fixed the aes-cbc bug.
This commit is contained in:
31
lib/crypto.c
31
lib/crypto.c
@@ -68,25 +68,32 @@ aes_ctx_t *aes_init(const uint8_t *key, const uint8_t *iv, const EVP_CIPHER *typ
|
||||
|
||||
memcpy(ctx->key, key, AES_128_BLOCK_SIZE);
|
||||
memcpy(ctx->iv, iv, AES_128_BLOCK_SIZE);
|
||||
EVP_CIPHER_CTX_set_padding(ctx->cipher_ctx, 0);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void aes_encrypt(aes_ctx_t *ctx, const uint8_t *in, uint8_t *out, int in_len) {
|
||||
int out_len = 0;
|
||||
if (!EVP_EncryptUpdate(ctx->cipher_ctx, out, &out_len, in, in_len)) {
|
||||
int out_len_e = 0;
|
||||
if (!EVP_EncryptUpdate(ctx->cipher_ctx, out, &out_len_e, in, in_len)) {
|
||||
handle_error(__func__);
|
||||
}
|
||||
|
||||
assert(out_len <= in_len);
|
||||
int out_len_f = in_len - out_len_e;
|
||||
if (!EVP_EncryptFinal_ex(ctx->cipher_ctx, out + out_len_e, &out_len_f)) {
|
||||
handle_error(__func__);
|
||||
}
|
||||
assert(out_len_e + out_len_f <= in_len);
|
||||
}
|
||||
|
||||
void aes_decrypt(aes_ctx_t *ctx, const uint8_t *in, uint8_t *out, int in_len) {
|
||||
int out_len = 0;
|
||||
if (!EVP_DecryptUpdate(ctx->cipher_ctx, out, &out_len, in, in_len)) {
|
||||
int out_len_d = 0;
|
||||
if (!EVP_DecryptUpdate(ctx->cipher_ctx, out, &out_len_d, in, in_len)) {
|
||||
handle_error(__func__);
|
||||
}
|
||||
|
||||
assert(out_len <= in_len);
|
||||
int out_len_f = in_len - out_len_d;
|
||||
if (!EVP_DecryptFinal_ex(ctx->cipher_ctx, out + out_len_d, &out_len_f)) {
|
||||
handle_error(__func__);
|
||||
}
|
||||
assert(out_len_f + out_len_d <= in_len);
|
||||
}
|
||||
|
||||
void aes_destroy(aes_ctx_t *ctx) {
|
||||
@@ -114,14 +121,10 @@ void aes_reset(aes_ctx_t *ctx, const EVP_CIPHER *type, aes_direction_t direction
|
||||
|
||||
// AES CTR
|
||||
|
||||
aes_ctx_t *aes_ctr_encrypt_init(const uint8_t *key, const uint8_t *iv) {
|
||||
aes_ctx_t *aes_ctr_init(const uint8_t *key, const uint8_t *iv) {
|
||||
return aes_init(key, iv, EVP_aes_128_ctr(), AES_ENCRYPT);
|
||||
}
|
||||
|
||||
aes_ctx_t *aes_ctr_decrypt_init(const uint8_t *key, const uint8_t *iv) {
|
||||
return aes_init(key, iv, EVP_aes_128_ctr(), AES_DECRYPT);
|
||||
}
|
||||
|
||||
void aes_ctr_encrypt(aes_ctx_t *ctx, const uint8_t *in, uint8_t *out, int len) {
|
||||
aes_encrypt(ctx, in, out, len);
|
||||
ctx->block_offset = (ctx->block_offset + len) % AES_128_BLOCK_SIZE;
|
||||
@@ -134,7 +137,7 @@ void aes_ctr_start_fresh_block(aes_ctx_t *ctx) {
|
||||
}
|
||||
|
||||
void aes_ctr_decrypt(aes_ctx_t *ctx, const uint8_t *in, uint8_t *out, int len) {
|
||||
aes_decrypt(ctx, in, out, len);
|
||||
aes_encrypt(ctx, in, out, len);
|
||||
}
|
||||
|
||||
void aes_ctr_reset(aes_ctx_t *ctx) {
|
||||
|
||||
@@ -41,8 +41,7 @@ typedef enum aes_direction_e { AES_DECRYPT, AES_ENCRYPT } aes_direction_t;
|
||||
|
||||
typedef struct aes_ctx_s aes_ctx_t;
|
||||
|
||||
aes_ctx_t *aes_ctr_encrypt_init(const uint8_t *key, const uint8_t *iv);
|
||||
aes_ctx_t *aes_ctr_decrypt_init(const uint8_t *key, const uint8_t *iv);
|
||||
aes_ctx_t *aes_ctr_init(const uint8_t *key, const uint8_t *iv);
|
||||
void aes_ctr_reset(aes_ctx_t *ctx);
|
||||
void aes_ctr_encrypt(aes_ctx_t *ctx, const uint8_t *in, uint8_t *out, int len);
|
||||
void aes_ctr_decrypt(aes_ctx_t *ctx, const uint8_t *in, uint8_t *out, int len);
|
||||
|
||||
@@ -77,7 +77,7 @@ mirror_buffer_init_aes(mirror_buffer_t *mirror_buffer, uint64_t streamConnection
|
||||
fclose(keyfile);
|
||||
#endif
|
||||
// Need to be initialized externally
|
||||
mirror_buffer->aes_ctx = aes_ctr_decrypt_init(decrypt_aeskey, decrypt_aesiv);
|
||||
mirror_buffer->aes_ctx = aes_ctr_init(decrypt_aeskey, decrypt_aesiv);
|
||||
mirror_buffer->nextDecryptCount = 0;
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ mirror_buffer_init(logger_t *logger,
|
||||
memcpy(mirror_buffer->ecdh_secret, ecdh_secret, 32);
|
||||
mirror_buffer->logger = logger;
|
||||
mirror_buffer->nextDecryptCount = 0;
|
||||
//mirror_buffer_init_aes(mirror_buffer, aeskey, ecdh_secret, streamConnectionID);
|
||||
return mirror_buffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ pairing_session_get_signature(pairing_session_t *session, unsigned char signatur
|
||||
derive_key_internal(session, (const unsigned char *) SALT_KEY, strlen(SALT_KEY), key, sizeof(key));
|
||||
derive_key_internal(session, (const unsigned char *) SALT_IV, strlen(SALT_IV), iv, sizeof(iv));
|
||||
|
||||
aes_ctx = aes_ctr_encrypt_init(key, iv);
|
||||
aes_ctx = aes_ctr_init(key, iv);
|
||||
aes_ctr_encrypt(aes_ctx, signature, signature, PAIRING_SIG_SIZE);
|
||||
aes_ctr_destroy(aes_ctx);
|
||||
|
||||
@@ -219,7 +219,7 @@ pairing_session_finish(pairing_session_t *session, const unsigned char signature
|
||||
derive_key_internal(session, (const unsigned char *) SALT_KEY, strlen(SALT_KEY), key, sizeof(key));
|
||||
derive_key_internal(session, (const unsigned char *) SALT_IV, strlen(SALT_IV), iv, sizeof(iv));
|
||||
|
||||
aes_ctx = aes_ctr_encrypt_init(key, iv);
|
||||
aes_ctx = aes_ctr_init(key, iv);
|
||||
/* One fake round for the initial handshake encryption */
|
||||
aes_ctr_encrypt(aes_ctx, sig_buffer, sig_buffer, PAIRING_SIG_SIZE);
|
||||
aes_ctr_encrypt(aes_ctx, signature, sig_buffer, PAIRING_SIG_SIZE);
|
||||
|
||||
@@ -170,24 +170,12 @@ raop_buffer_decrypt(raop_buffer_t *raop_buffer, unsigned char *data, unsigned ch
|
||||
fwrite(&data[12], payloadsize, 1, file_source);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Need to be initialized externally */
|
||||
aes_ctx_t *aes_ctx_audio = aes_cbc_init(raop_buffer->aeskey, raop_buffer->aesiv, AES_DECRYPT);
|
||||
|
||||
encryptedlen = (payload_size / 16) * 16;
|
||||
encryptedlen = payload_size / 16*16;
|
||||
memset(output, 0, payload_size);
|
||||
|
||||
/* Adding 15 to encryptedlen in the call to aes_cbc_decrypt is a fix (hack) to ensure that */
|
||||
/* all encryptedlen encrypted bytes are decrypted .*/
|
||||
/* The implementation of aes_cbc_decrypt in crypto.c calls OpenSSL function EVP_EncryptUpdate */
|
||||
/* but does not call EVP_EncryptFinal to finalize the decryption of the packet. */
|
||||
/* Instead the finalization of the < 16 remaining (unencrypted) bytes is done here. */
|
||||
/* Without the fix, the last 16 encrypted bytes are lost by EVP_EncryptUpdate; */
|
||||
/* with the fix all (encryptedlen + 15) /16 * 16 = encryptedlen decrypted encrypted-bytes are */
|
||||
/* written into output, with no risk of buffer overflow */
|
||||
|
||||
aes_cbc_decrypt(aes_ctx_audio, &data[12], output, encryptedlen + 15);
|
||||
|
||||
// Need to be initialized internally
|
||||
aes_ctx_t *aes_ctx_audio = aes_cbc_init(raop_buffer->aeskey, raop_buffer->aesiv, AES_DECRYPT);
|
||||
aes_cbc_decrypt(aes_ctx_audio, &data[12], output, encryptedlen);
|
||||
aes_cbc_destroy(aes_ctx_audio);
|
||||
|
||||
memcpy(output + encryptedlen, &data[12 + encryptedlen], payload_size - encryptedlen);
|
||||
|
||||
Reference in New Issue
Block a user