Originally committed as revision 16970 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -136,6 +136,8 @@ static uint64_t multiswap_dec(const uint32_t keys[12], uint64_t key, uint64_t da |
| 136 | 136 |
} |
| 137 | 137 |
|
| 138 | 138 |
void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len) {
|
| 139 |
+ struct AVDES des; |
|
| 140 |
+ struct AVRC4 rc4; |
|
| 139 | 141 |
int num_qwords = len >> 3; |
| 140 | 142 |
uint64_t *qwords = (uint64_t *)data; |
| 141 | 143 |
uint64_t rc4buff[8]; |
| ... | ... |
@@ -150,17 +152,18 @@ void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len) {
|
| 150 | 150 |
} |
| 151 | 151 |
|
| 152 | 152 |
memset(rc4buff, 0, sizeof(rc4buff)); |
| 153 |
- ff_rc4_enc(key, 12, (uint8_t *)rc4buff, sizeof(rc4buff)); |
|
| 153 |
+ av_rc4_init(&rc4, key, 12 * 8, 1); |
|
| 154 |
+ av_rc4_crypt(&rc4, (uint8_t *)rc4buff, NULL, sizeof(rc4buff), NULL, 1); |
|
| 154 | 155 |
multiswap_init((uint8_t *)rc4buff, ms_keys); |
| 155 | 156 |
|
| 156 | 157 |
packetkey = qwords[num_qwords - 1]; |
| 157 | 158 |
packetkey ^= rc4buff[7]; |
| 158 |
- packetkey = be2me_64(packetkey); |
|
| 159 |
- packetkey = ff_des_encdec(packetkey, AV_RB64(key + 12), 1); |
|
| 160 |
- packetkey = be2me_64(packetkey); |
|
| 159 |
+ av_des_init(&des, key + 12, 64, 1); |
|
| 160 |
+ av_des_crypt(&des, (uint8_t *)&packetkey, (uint8_t *)&packetkey, 1, NULL, 1); |
|
| 161 | 161 |
packetkey ^= rc4buff[6]; |
| 162 | 162 |
|
| 163 |
- ff_rc4_enc((uint8_t *)&packetkey, 8, data, len); |
|
| 163 |
+ av_rc4_init(&rc4, (uint8_t *)&packetkey, 64, 1); |
|
| 164 |
+ av_rc4_crypt(&rc4, data, data, len, NULL, 1); |
|
| 164 | 165 |
|
| 165 | 166 |
ms_state = 0; |
| 166 | 167 |
for (i = 0; i < num_qwords - 1; i++, qwords++) |
| ... | ... |
@@ -19,9 +19,13 @@ |
| 19 | 19 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | 20 |
*/ |
| 21 | 21 |
#include <inttypes.h> |
| 22 |
+#include "avutil.h" |
|
| 22 | 23 |
#include "common.h" |
| 24 |
+#include "intreadwrite.h" |
|
| 23 | 25 |
#include "des.h" |
| 24 | 26 |
|
| 27 |
+typedef struct AVDES AVDES; |
|
| 28 |
+ |
|
| 25 | 29 |
#define T(a, b, c, d, e, f, g, h) 64-a,64-b,64-c,64-d,64-e,64-f,64-g,64-h |
| 26 | 30 |
static const uint8_t IP_shuffle[] = {
|
| 27 | 31 |
T(58, 50, 42, 34, 26, 18, 10, 2), |
| ... | ... |
@@ -249,9 +253,8 @@ static uint64_t key_shift_left(uint64_t CDn) {
|
| 249 | 249 |
return CDn; |
| 250 | 250 |
} |
| 251 | 251 |
|
| 252 |
-uint64_t ff_des_encdec(uint64_t in, uint64_t key, int decrypt) {
|
|
| 252 |
+static void gen_roundkeys(uint64_t K[16], uint64_t key) {
|
|
| 253 | 253 |
int i; |
| 254 |
- uint64_t K[16]; |
|
| 255 | 254 |
// discard parity bits from key and shuffle it into C and D parts |
| 256 | 255 |
uint64_t CDn = shuffle(key, PC1_shuffle, sizeof(PC1_shuffle)); |
| 257 | 256 |
// generate round keys |
| ... | ... |
@@ -261,6 +264,10 @@ uint64_t ff_des_encdec(uint64_t in, uint64_t key, int decrypt) {
|
| 261 | 261 |
CDn = key_shift_left(CDn); |
| 262 | 262 |
K[i] = shuffle(CDn, PC2_shuffle, sizeof(PC2_shuffle)); |
| 263 | 263 |
} |
| 264 |
+} |
|
| 265 |
+ |
|
| 266 |
+static uint64_t des_encdec(uint64_t in, uint64_t K[16], int decrypt) {
|
|
| 267 |
+ int i; |
|
| 264 | 268 |
// used to apply round keys in reverse order for decryption |
| 265 | 269 |
decrypt = decrypt ? 15 : 0; |
| 266 | 270 |
// shuffle irrelevant to security but to ease hardware implementations |
| ... | ... |
@@ -277,6 +284,42 @@ uint64_t ff_des_encdec(uint64_t in, uint64_t key, int decrypt) {
|
| 277 | 277 |
return in; |
| 278 | 278 |
} |
| 279 | 279 |
|
| 280 |
+#if LIBAVUTIL_VERSION_MAJOR < 50 |
|
| 281 |
+uint64_t ff_des_encdec(uint64_t in, uint64_t key, int decrypt) {
|
|
| 282 |
+ uint64_t K[16]; |
|
| 283 |
+ gen_roundkeys(K, key); |
|
| 284 |
+ return des_encdec(in, K, decrypt); |
|
| 285 |
+} |
|
| 286 |
+#endif |
|
| 287 |
+ |
|
| 288 |
+int av_des_init(AVDES *d, const uint8_t *key, int key_bits, int decrypt) {
|
|
| 289 |
+ if (key_bits != 64) |
|
| 290 |
+ return -1; |
|
| 291 |
+ d->triple_des = 0; |
|
| 292 |
+ gen_roundkeys(d->round_keys[0], AV_RB64(key)); |
|
| 293 |
+ return 0; |
|
| 294 |
+} |
|
| 295 |
+ |
|
| 296 |
+void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) {
|
|
| 297 |
+ uint64_t iv_val = iv ? be2me_64(*(uint64_t *)iv) : 0; |
|
| 298 |
+ while (count-- > 0) {
|
|
| 299 |
+ uint64_t dst_val; |
|
| 300 |
+ uint64_t src_val = src ? be2me_64(*(const uint64_t *)src) : 0; |
|
| 301 |
+ if (decrypt) {
|
|
| 302 |
+ dst_val = des_encdec(src_val, d->round_keys[0], 1) ^ iv_val; |
|
| 303 |
+ iv_val = iv ? src_val : 0; |
|
| 304 |
+ } else {
|
|
| 305 |
+ dst_val = des_encdec(src_val ^ iv_val, d->round_keys[0], 0); |
|
| 306 |
+ iv_val = iv ? dst_val : 0; |
|
| 307 |
+ } |
|
| 308 |
+ *(uint64_t *)dst = be2me_64(dst_val); |
|
| 309 |
+ src += 8; |
|
| 310 |
+ dst += 8; |
|
| 311 |
+ } |
|
| 312 |
+ if (iv) |
|
| 313 |
+ *(uint64_t *)iv = be2me_64(iv_val); |
|
| 314 |
+} |
|
| 315 |
+ |
|
| 280 | 316 |
#ifdef TEST |
| 281 | 317 |
#undef printf |
| 282 | 318 |
#undef rand |
| ... | ... |
@@ -23,18 +23,30 @@ |
| 23 | 23 |
#define AVUTIL_DES_H |
| 24 | 24 |
|
| 25 | 25 |
#include <stdint.h> |
| 26 |
-#include "common.h" |
|
| 26 |
+ |
|
| 27 |
+struct AVDES {
|
|
| 28 |
+ uint64_t round_keys[3][16]; |
|
| 29 |
+ int triple_des; |
|
| 30 |
+}; |
|
| 31 |
+ |
|
| 32 |
+/** |
|
| 33 |
+ * \brief Initializes an AVDES context. |
|
| 34 |
+ * |
|
| 35 |
+ * \param key_bits must be 64 |
|
| 36 |
+ * \param decrypt 0 for encryption, 1 for decryption |
|
| 37 |
+ */ |
|
| 38 |
+int av_des_init(struct AVDES *d, const uint8_t *key, int key_bits, int decrypt); |
|
| 27 | 39 |
|
| 28 | 40 |
/** |
| 29 |
- * \brief Encrypt/decrypt a 64-bit block of data with DES. |
|
| 30 |
- * \param in data to process |
|
| 31 |
- * \param key key to use for encryption/decryption |
|
| 32 |
- * \param decrypt if 0 encrypt, else decrypt |
|
| 33 |
- * \return processed data |
|
| 41 |
+ * \brief Encrypts / decrypts using the DES algorithm. |
|
| 34 | 42 |
* |
| 35 |
- * If your input data is in 8-bit blocks, treat it as big-endian |
|
| 36 |
- * (use e.g. AV_RB64 and AV_WB64). |
|
| 43 |
+ * \param count number of 8 byte blocks |
|
| 44 |
+ * \param dst destination array, can be equal to src, must be 8-byte aligned |
|
| 45 |
+ * \param src source array, can be equal to dst, must be 8-byte aligned, may be NULL |
|
| 46 |
+ * \param iv initialization vector for CBC mode, if NULL then ECB will be used, |
|
| 47 |
+ * must be 8-byte aligned |
|
| 48 |
+ * \param decrypt 0 for encryption, 1 for decryption |
|
| 37 | 49 |
*/ |
| 38 |
-uint64_t ff_des_encdec(uint64_t in, uint64_t key, int decrypt) av_const; |
|
| 50 |
+void av_des_crypt(struct AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); |
|
| 39 | 51 |
|
| 40 | 52 |
#endif /* AVUTIL_DES_H */ |
| ... | ... |
@@ -20,13 +20,19 @@ |
| 20 | 20 |
* License along with FFmpeg; if not, write to the Free Software |
| 21 | 21 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 22 | 22 |
*/ |
| 23 |
+#include "avutil.h" |
|
| 23 | 24 |
#include "common.h" |
| 24 | 25 |
#include "rc4.h" |
| 25 | 26 |
|
| 26 |
-void ff_rc4_enc(const uint8_t *key, int keylen, uint8_t *data, int datalen) {
|
|
| 27 |
+typedef struct AVRC4 AVRC4; |
|
| 28 |
+ |
|
| 29 |
+int av_rc4_init(AVRC4 *r, const uint8_t *key, int key_bits, int decrypt) {
|
|
| 27 | 30 |
int i, j; |
| 28 |
- uint8_t x, y; |
|
| 29 |
- uint8_t state[256]; |
|
| 31 |
+ uint8_t y; |
|
| 32 |
+ uint8_t *state = r->state; |
|
| 33 |
+ int keylen = key_bits >> 3; |
|
| 34 |
+ if (key_bits & 7) |
|
| 35 |
+ return -1; |
|
| 30 | 36 |
for (i = 0; i < 256; i++) |
| 31 | 37 |
state[i] = i; |
| 32 | 38 |
y = 0; |
| ... | ... |
@@ -36,13 +42,28 @@ void ff_rc4_enc(const uint8_t *key, int keylen, uint8_t *data, int datalen) {
|
| 36 | 36 |
y += state[i] + key[j]; |
| 37 | 37 |
FFSWAP(uint8_t, state[i], state[y]); |
| 38 | 38 |
} |
| 39 |
- // state initialized, now do the real encryption |
|
| 40 |
- x = 1; y = state[1]; |
|
| 41 |
- while (datalen-- > 0) {
|
|
| 39 |
+ r->x = 1; |
|
| 40 |
+ r->y = state[1]; |
|
| 41 |
+ return 0; |
|
| 42 |
+} |
|
| 43 |
+ |
|
| 44 |
+void av_rc4_crypt(AVRC4 *r, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) {
|
|
| 45 |
+ uint8_t x = r->x, y = r->y; |
|
| 46 |
+ uint8_t *state = r->state; |
|
| 47 |
+ while (count-- > 0) {
|
|
| 42 | 48 |
uint8_t sum = state[x] + state[y]; |
| 43 | 49 |
FFSWAP(uint8_t, state[x], state[y]); |
| 44 |
- *data++ ^= state[sum]; |
|
| 50 |
+ *dst++ = src ? *src++ ^ state[sum] : state[sum]; |
|
| 45 | 51 |
x++; |
| 46 | 52 |
y += state[x]; |
| 47 | 53 |
} |
| 54 |
+ r->x = x; r->y = y; |
|
| 55 |
+} |
|
| 56 |
+ |
|
| 57 |
+#if LIBAVUTIL_VERSION_MAJOR < 50 |
|
| 58 |
+void ff_rc4_enc(const uint8_t *key, int keylen, uint8_t *data, int datalen) {
|
|
| 59 |
+ AVRC4 r; |
|
| 60 |
+ av_rc4_init(&r, key, keylen * 8, 0); |
|
| 61 |
+ av_rc4_crypt(&r, data, data, datalen, NULL, 0); |
|
| 48 | 62 |
} |
| 63 |
+#endif |
| ... | ... |
@@ -23,6 +23,28 @@ |
| 23 | 23 |
|
| 24 | 24 |
#include <stdint.h> |
| 25 | 25 |
|
| 26 |
-void ff_rc4_enc(const uint8_t *key, int keylen, uint8_t *data, int datalen); |
|
| 26 |
+struct AVRC4 {
|
|
| 27 |
+ uint8_t state[256]; |
|
| 28 |
+ int x, y; |
|
| 29 |
+}; |
|
| 30 |
+ |
|
| 31 |
+/** |
|
| 32 |
+ * \brief Initializes an AVRC4 context. |
|
| 33 |
+ * |
|
| 34 |
+ * \param key_bits must be a multiple of 8 |
|
| 35 |
+ * \param decrypt 0 for encryption, 1 for decryption, currently has no effect |
|
| 36 |
+ */ |
|
| 37 |
+int av_rc4_init(struct AVRC4 *d, const uint8_t *key, int key_bits, int decrypt); |
|
| 38 |
+ |
|
| 39 |
+/** |
|
| 40 |
+ * \brief Encrypts / decrypts using the RC4 algorithm. |
|
| 41 |
+ * |
|
| 42 |
+ * \param count number of bytes |
|
| 43 |
+ * \param dst destination array, can be equal to src |
|
| 44 |
+ * \param src source array, can be equal to dst, may be NULL |
|
| 45 |
+ * \param iv not (yet) used for RC4, should be NULL |
|
| 46 |
+ * \param decrypt 0 for encryption, 1 for decryption, not (yet) used |
|
| 47 |
+ */ |
|
| 48 |
+void av_rc4_crypt(struct AVRC4 *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); |
|
| 27 | 49 |
|
| 28 | 50 |
#endif /* AVUTIL_RC4_H */ |