3 * Copyright (c) 2015 Eran Kornblau <erankor at gmail dot com>
5 * This file is part of FFmpeg.
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.
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.
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
26 #include "aes_internal.h"
27 #include "intreadwrite.h"
30 #include "random_seed.h"
32 #define AES_BLOCK_SIZE (16)
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
];
41 struct AVAESCTR
*av_aes_ctr_alloc(void)
43 return av_mallocz(sizeof(struct AVAESCTR
));
46 void av_aes_ctr_set_iv(struct AVAESCTR
*a
, const uint8_t* iv
)
48 memcpy(a
->counter
, iv
, AES_CTR_IV_SIZE
);
49 memset(a
->counter
+ AES_CTR_IV_SIZE
, 0, sizeof(a
->counter
) - AES_CTR_IV_SIZE
);
53 void av_aes_ctr_set_full_iv(struct AVAESCTR
*a
, const uint8_t* iv
)
55 memcpy(a
->counter
, iv
, sizeof(a
->counter
));
59 const uint8_t* av_aes_ctr_get_iv(struct AVAESCTR
*a
)
64 void av_aes_ctr_set_random_iv(struct AVAESCTR
*a
)
68 iv
[0] = av_get_random_seed();
69 iv
[1] = av_get_random_seed();
71 av_aes_ctr_set_iv(a
, (uint8_t*)iv
);
74 int av_aes_ctr_init(struct AVAESCTR
*a
, const uint8_t *key
)
76 av_aes_init(&a
->aes
, key
, 128, 0);
78 memset(a
->counter
, 0, sizeof(a
->counter
));
84 void av_aes_ctr_free(struct AVAESCTR
*a
)
89 static inline void av_aes_ctr_increment_be64(uint8_t* counter
)
91 uint64_t c
= AV_RB64A(counter
) + 1;
95 void av_aes_ctr_increment_iv(struct AVAESCTR
*a
)
97 av_aes_ctr_increment_be64(a
->counter
);
98 memset(a
->counter
+ AES_CTR_IV_SIZE
, 0, sizeof(a
->counter
) - AES_CTR_IV_SIZE
);
102 void av_aes_ctr_crypt(struct AVAESCTR
*a
, uint8_t *dst
, const uint8_t *src
, int count
)
104 if (a
->block_offset
&& count
> 0) {
105 int left
= FFMIN(count
, AES_BLOCK_SIZE
- a
->block_offset
);
106 for (int len
= 0; len
< left
; len
++)
107 dst
[len
] = src
[len
] ^ a
->encrypted_counter
[a
->block_offset
++];
108 a
->block_offset
&= AES_BLOCK_SIZE
- 1;
114 while (count
>= AES_BLOCK_SIZE
) {
115 av_aes_crypt(&a
->aes
, a
->encrypted_counter
, a
->counter
, 1, NULL
, 0);
116 av_aes_ctr_increment_be64(a
->counter
+ 8);
118 for (int len
= 0; len
< AES_BLOCK_SIZE
; len
+= 8)
119 AV_WN64(&dst
[len
], AV_RN64(&src
[len
]) ^ AV_RN64A(&a
->encrypted_counter
[len
]));
121 for (int len
= 0; len
< AES_BLOCK_SIZE
; len
+= 4)
122 AV_WN32(&dst
[len
], AV_RN32(&src
[len
]) ^ AV_RN32A(&a
->encrypted_counter
[len
]));
124 dst
+= AES_BLOCK_SIZE
;
125 src
+= AES_BLOCK_SIZE
;
126 count
-= AES_BLOCK_SIZE
;
130 av_aes_crypt(&a
->aes
, a
->encrypted_counter
, a
->counter
, 1, NULL
, 0);
131 av_aes_ctr_increment_be64(a
->counter
+ 8);
132 for (int len
= 0; len
< count
; len
++)
133 dst
[len
] = src
[len
] ^ a
->encrypted_counter
[a
->block_offset
++];