Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * AES-CTR cipher | ||
3 | * Copyright (c) 2015 Eran Kornblau <erankor at gmail dot com> | ||
4 | * | ||
5 | * This file is part of FFmpeg. | ||
6 | * | ||
7 | * FFmpeg is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * FFmpeg is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with FFmpeg; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | |||
22 | #include <string.h> | ||
23 | |||
24 | #include "aes_ctr.h" | ||
25 | #include "aes.h" | ||
26 | #include "aes_internal.h" | ||
27 | #include "intreadwrite.h" | ||
28 | #include "macros.h" | ||
29 | #include "mem.h" | ||
30 | #include "random_seed.h" | ||
31 | |||
32 | #define AES_BLOCK_SIZE (16) | ||
33 | |||
34 | typedef struct AVAESCTR { | ||
35 | DECLARE_ALIGNED(8, uint8_t, counter)[AES_BLOCK_SIZE]; | ||
36 | DECLARE_ALIGNED(8, uint8_t, encrypted_counter)[AES_BLOCK_SIZE]; | ||
37 | AVAES aes; | ||
38 | } AVAESCTR; | ||
39 | |||
40 | 7 | struct AVAESCTR *av_aes_ctr_alloc(void) | |
41 | { | ||
42 | 7 | return av_mallocz(sizeof(struct AVAESCTR)); | |
43 | } | ||
44 | |||
45 | 2 | void av_aes_ctr_set_iv(struct AVAESCTR *a, const uint8_t* iv) | |
46 | { | ||
47 | 2 | memcpy(a->counter, iv, AES_CTR_IV_SIZE); | |
48 | 2 | memset(a->counter + AES_CTR_IV_SIZE, 0, sizeof(a->counter) - AES_CTR_IV_SIZE); | |
49 | 2 | } | |
50 | |||
51 | 148 | void av_aes_ctr_set_full_iv(struct AVAESCTR *a, const uint8_t* iv) | |
52 | { | ||
53 | 148 | memcpy(a->counter, iv, sizeof(a->counter)); | |
54 | 148 | } | |
55 | |||
56 | 2 | const uint8_t* av_aes_ctr_get_iv(struct AVAESCTR *a) | |
57 | { | ||
58 | 2 | return a->counter; | |
59 | } | ||
60 | |||
61 | 1 | void av_aes_ctr_set_random_iv(struct AVAESCTR *a) | |
62 | { | ||
63 | uint32_t iv[2]; | ||
64 | |||
65 | 1 | iv[0] = av_get_random_seed(); | |
66 | 1 | iv[1] = av_get_random_seed(); | |
67 | |||
68 | 1 | av_aes_ctr_set_iv(a, (uint8_t*)iv); | |
69 | 1 | } | |
70 | |||
71 | 7 | int av_aes_ctr_init(struct AVAESCTR *a, const uint8_t *key) | |
72 | { | ||
73 | 7 | av_aes_init(&a->aes, key, 128, 0); | |
74 | |||
75 | 7 | memset(a->counter, 0, sizeof(a->counter)); | |
76 | |||
77 | 7 | return 0; | |
78 | } | ||
79 | |||
80 | 913 | void av_aes_ctr_free(struct AVAESCTR *a) | |
81 | { | ||
82 | 913 | av_free(a); | |
83 | 913 | } | |
84 | |||
85 | 5189 | static inline void av_aes_ctr_increment_be64(uint8_t* counter) | |
86 | { | ||
87 | 5189 | uint64_t c = AV_RB64A(counter) + 1; | |
88 | 5189 | AV_WB64A(counter, c); | |
89 | 5189 | } | |
90 | |||
91 | ✗ | void av_aes_ctr_increment_iv(struct AVAESCTR *a) | |
92 | { | ||
93 | ✗ | av_aes_ctr_increment_be64(a->counter); | |
94 | ✗ | memset(a->counter + AES_CTR_IV_SIZE, 0, sizeof(a->counter) - AES_CTR_IV_SIZE); | |
95 | ✗ | } | |
96 | |||
97 | 150 | void av_aes_ctr_crypt(struct AVAESCTR *a, uint8_t *dst, const uint8_t *src, int count) | |
98 | { | ||
99 |
2/2✓ Branch 0 taken 5069 times.
✓ Branch 1 taken 150 times.
|
5219 | while (count >= AES_BLOCK_SIZE) { |
100 | 5069 | av_aes_crypt(&a->aes, a->encrypted_counter, a->counter, 1, NULL, 0); | |
101 | 5069 | av_aes_ctr_increment_be64(a->counter + 8); | |
102 | #if HAVE_FAST_64BIT | ||
103 |
2/2✓ Branch 0 taken 10138 times.
✓ Branch 1 taken 5069 times.
|
15207 | for (int len = 0; len < AES_BLOCK_SIZE; len += 8) |
104 | 10138 | AV_WN64(&dst[len], AV_RN64(&src[len]) ^ AV_RN64A(&a->encrypted_counter[len])); | |
105 | #else | ||
106 | for (int len = 0; len < AES_BLOCK_SIZE; len += 4) | ||
107 | AV_WN32(&dst[len], AV_RN32(&src[len]) ^ AV_RN32A(&a->encrypted_counter[len])); | ||
108 | #endif | ||
109 | 5069 | dst += AES_BLOCK_SIZE; | |
110 | 5069 | src += AES_BLOCK_SIZE; | |
111 | 5069 | count -= AES_BLOCK_SIZE; | |
112 | } | ||
113 | |||
114 |
2/2✓ Branch 0 taken 120 times.
✓ Branch 1 taken 30 times.
|
150 | if (count > 0) { |
115 | 120 | av_aes_crypt(&a->aes, a->encrypted_counter, a->counter, 1, NULL, 0); | |
116 | 120 | av_aes_ctr_increment_be64(a->counter + 8); | |
117 |
2/2✓ Branch 0 taken 981 times.
✓ Branch 1 taken 120 times.
|
1101 | for (int len = 0; len < count; len++) |
118 | 981 | dst[len] = src[len] ^ a->encrypted_counter[len]; | |
119 | } | ||
120 | 150 | } | |
121 |