summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerankor <eran.kornblau@kaltura.com>2015-12-07 11:58:41 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2015-12-15 14:16:28 +0100
commit23ac99dc17b0c4ff43bb56c1f8cbe7feb34bada5 (patch)
tree6d644b6a721cc291e06bd21d9cdbfb39dbe8813b
parentc54632d3811d0515a5407f081056ae08e9a1c54c (diff)
libavutil: add aes-ctr support
for supporting mp4 cenc encoding/decoding Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r--libavutil/Makefile2
-rw-r--r--libavutil/aes_ctr.c129
-rw-r--r--libavutil/aes_ctr.h83
-rw-r--r--libavutil/version.h2
4 files changed, 215 insertions, 1 deletions
diff --git a/libavutil/Makefile b/libavutil/Makefile
index b43cede0c2..bf8c713e9f 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -4,6 +4,7 @@ NAME = avutil
HEADERS = adler32.h \
aes.h \
+ aes_ctr.h \
attributes.h \
audio_fifo.h \
avassert.h \
@@ -80,6 +81,7 @@ BUILT_HEADERS = avconfig.h \
OBJS = adler32.o \
aes.o \
+ aes_ctr.o \
audio_fifo.o \
avstring.o \
base64.o \
diff --git a/libavutil/aes_ctr.c b/libavutil/aes_ctr.c
new file mode 100644
index 0000000000..234354374f
--- /dev/null
+++ b/libavutil/aes_ctr.c
@@ -0,0 +1,129 @@
+/*
+ * AES-CTR cipher
+ * Copyright (c) 2015 Eran Kornblau <erankor at gmail dot com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "common.h"
+#include "aes_ctr.h"
+#include "aes.h"
+#include "random_seed.h"
+
+#define AES_BLOCK_SIZE (16)
+
+typedef struct AVAESCTR {
+ struct AVAES* aes;
+ uint8_t counter[AES_BLOCK_SIZE];
+ uint8_t encrypted_counter[AES_BLOCK_SIZE];
+ int block_offset;
+} AVAESCTR;
+
+struct AVAESCTR *av_aes_ctr_alloc(void)
+{
+ return av_mallocz(sizeof(struct AVAESCTR));
+}
+
+void av_aes_ctr_set_iv(struct AVAESCTR *a, const uint8_t* iv)
+{
+ memcpy(a->counter, iv, AES_CTR_IV_SIZE);
+ memset(a->counter + AES_CTR_IV_SIZE, 0, sizeof(a->counter) - AES_CTR_IV_SIZE);
+ a->block_offset = 0;
+}
+
+const uint8_t* av_aes_ctr_get_iv(struct AVAESCTR *a)
+{
+ return a->counter;
+}
+
+void av_aes_ctr_set_random_iv(struct AVAESCTR *a)
+{
+ uint32_t iv[2];
+
+ iv[0] = av_get_random_seed();
+ iv[1] = av_get_random_seed();
+
+ av_aes_ctr_set_iv(a, (uint8_t*)iv);
+}
+
+int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key)
+{
+ a->aes = av_aes_alloc();
+ if (!a->aes) {
+ return AVERROR(ENOMEM);
+ }
+
+ av_aes_init(a->aes, key, 128, 0);
+
+ memset(a->counter, 0, sizeof(a->counter));
+ a->block_offset = 0;
+
+ return 0;
+}
+
+void av_aes_ctr_free(struct AVAESCTR *a)
+{
+ if (a) {
+ av_freep(&a->aes);
+ av_freep(a);
+ }
+}
+
+static void av_aes_ctr_increment_be64(uint8_t* counter)
+{
+ uint8_t* cur_pos;
+
+ for (cur_pos = counter + 7; cur_pos >= counter; cur_pos--) {
+ (*cur_pos)++;
+ if (*cur_pos != 0) {
+ break;
+ }
+ }
+}
+
+void av_aes_ctr_increment_iv(struct AVAESCTR *a)
+{
+ av_aes_ctr_increment_be64(a->counter);
+ memset(a->counter + AES_CTR_IV_SIZE, 0, sizeof(a->counter) - AES_CTR_IV_SIZE);
+ a->block_offset = 0;
+}
+
+void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count)
+{
+ const uint8_t* src_end = src + count;
+ const uint8_t* cur_end_pos;
+ uint8_t* encrypted_counter_pos;
+
+ while (src < src_end) {
+ if (a->block_offset == 0) {
+ av_aes_crypt(a->aes, a->encrypted_counter, a->counter, 1, NULL, 0);
+
+ av_aes_ctr_increment_be64(a->counter + 8);
+ }
+
+ encrypted_counter_pos = a->encrypted_counter + a->block_offset;
+ cur_end_pos = src + AES_BLOCK_SIZE - a->block_offset;
+ cur_end_pos = FFMIN(cur_end_pos, src_end);
+
+ a->block_offset += cur_end_pos - src;
+ a->block_offset &= (AES_BLOCK_SIZE - 1);
+
+ while (src < cur_end_pos) {
+ *dst++ = *src++ ^ *encrypted_counter_pos++;
+ }
+ }
+}
diff --git a/libavutil/aes_ctr.h b/libavutil/aes_ctr.h
new file mode 100644
index 0000000000..f596fa6a46
--- /dev/null
+++ b/libavutil/aes_ctr.h
@@ -0,0 +1,83 @@
+/*
+ * AES-CTR cipher
+ * Copyright (c) 2015 Eran Kornblau <erankor at gmail dot com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_AES_CTR_H
+#define AVUTIL_AES_CTR_H
+
+#include <stdint.h>
+
+#include "attributes.h"
+#include "version.h"
+
+#define AES_CTR_KEY_SIZE (16)
+#define AES_CTR_IV_SIZE (8)
+
+struct AVAESCTR;
+
+/**
+ * Allocate an AVAESCTR context.
+ */
+struct AVAESCTR *av_aes_ctr_alloc(void);
+
+/**
+ * Initialize an AVAESCTR context.
+ * @param key encryption key, must have a length of AES_CTR_KEY_SIZE
+ */
+int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key);
+
+/**
+ * Release an AVAESCTR context.
+ */
+void av_aes_ctr_free(struct AVAESCTR *a);
+
+/**
+ * Process a buffer using a previously initialized context.
+ * @param dst destination array, can be equal to src
+ * @param src source array, can be equal to dst
+ * @param size the size of src and dst
+ */
+void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int size);
+
+/**
+ * Get the current iv
+ */
+const uint8_t* av_aes_ctr_get_iv(struct AVAESCTR *a);
+
+/**
+ * Generate a random iv
+ */
+void av_aes_ctr_set_random_iv(struct AVAESCTR *a);
+
+/**
+ * Forcefully change the iv
+ */
+void av_aes_ctr_set_iv(struct AVAESCTR *a, const uint8_t* iv);
+
+/**
+ * Increment the top 64 bit of the iv (performed after each frame)
+ */
+void av_aes_ctr_increment_iv(struct AVAESCTR *a);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_AES_CTR_H */
diff --git a/libavutil/version.h b/libavutil/version.h
index e7f04888de..22cd66b554 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -64,7 +64,7 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 55
-#define LIBAVUTIL_VERSION_MINOR 10
+#define LIBAVUTIL_VERSION_MINOR 11
#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \