FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
asfcrypt.c
Go to the documentation of this file.
1 /*
2  * ASF decryption
3  * Copyright (c) 2007 Reimar Doeffinger
4  * This is a rewrite of code contained in freeme/freeme2
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "libavutil/bswap.h"
24 #include "libavutil/common.h"
25 #include "libavutil/des.h"
26 #include "libavutil/intreadwrite.h"
27 #include "libavutil/rc4.h"
28 #include "asfcrypt.h"
29 
30 /**
31  * @brief find multiplicative inverse modulo 2 ^ 32
32  * @param v number to invert, must be odd!
33  * @return number so that result * v = 1 (mod 2^32)
34  */
35 static uint32_t inverse(uint32_t v)
36 {
37  // v ^ 3 gives the inverse (mod 16), could also be implemented
38  // as table etc. (only lowest 4 bits matter!)
39  uint32_t inverse = v * v * v;
40  // uses a fixpoint-iteration that doubles the number
41  // of correct lowest bits each time
42  inverse *= 2 - v * inverse;
43  inverse *= 2 - v * inverse;
44  inverse *= 2 - v * inverse;
45  return inverse;
46 }
47 
48 /**
49  * @brief read keys from keybuf into keys
50  * @param keybuf buffer containing the keys
51  * @param keys output key array containing the keys for encryption in
52  * native endianness
53  */
54 static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12])
55 {
56  int i;
57  for (i = 0; i < 12; i++)
58  keys[i] = AV_RL32(keybuf + (i << 2)) | 1;
59 }
60 
61 /**
62  * @brief invert the keys so that encryption become decryption keys and
63  * the other way round.
64  * @param keys key array of ints to invert
65  */
66 static void multiswap_invert_keys(uint32_t keys[12])
67 {
68  int i;
69  for (i = 0; i < 5; i++)
70  keys[i] = inverse(keys[i]);
71  for (i = 6; i < 11; i++)
72  keys[i] = inverse(keys[i]);
73 }
74 
75 static uint32_t multiswap_step(const uint32_t keys[12], uint32_t v)
76 {
77  int i;
78  v *= keys[0];
79  for (i = 1; i < 5; i++) {
80  v = (v >> 16) | (v << 16);
81  v *= keys[i];
82  }
83  v += keys[5];
84  return v;
85 }
86 
87 static uint32_t multiswap_inv_step(const uint32_t keys[12], uint32_t v)
88 {
89  int i;
90  v -= keys[5];
91  for (i = 4; i > 0; i--) {
92  v *= keys[i];
93  v = (v >> 16) | (v << 16);
94  }
95  v *= keys[0];
96  return v;
97 }
98 
99 /**
100  * @brief "MultiSwap" encryption
101  * @param keys 32 bit numbers in machine endianness,
102  * 0-4 and 6-10 must be inverted from decryption
103  * @param key another key, this one must be the same for the decryption
104  * @param data data to encrypt
105  * @return encrypted data
106  */
107 static uint64_t multiswap_enc(const uint32_t keys[12],
108  uint64_t key, uint64_t data)
109 {
110  uint32_t a = data;
111  uint32_t b = data >> 32;
112  uint32_t c;
113  uint32_t tmp;
114  a += key;
115  tmp = multiswap_step(keys, a);
116  b += tmp;
117  c = (key >> 32) + tmp;
118  tmp = multiswap_step(keys + 6, b);
119  c += tmp;
120  return ((uint64_t)c << 32) | tmp;
121 }
122 
123 /**
124  * @brief "MultiSwap" decryption
125  * @param keys 32 bit numbers in machine endianness,
126  * 0-4 and 6-10 must be inverted from encryption
127  * @param key another key, this one must be the same as for the encryption
128  * @param data data to decrypt
129  * @return decrypted data
130  */
131 static uint64_t multiswap_dec(const uint32_t keys[12],
132  uint64_t key, uint64_t data)
133 {
134  uint32_t a;
135  uint32_t b;
136  uint32_t c = data >> 32;
137  uint32_t tmp = data;
138  c -= tmp;
139  b = multiswap_inv_step(keys + 6, tmp);
140  tmp = c - (key >> 32);
141  b -= tmp;
142  a = multiswap_inv_step(keys, tmp);
143  a -= key;
144  return ((uint64_t)b << 32) | a;
145 }
146 
147 void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len)
148 {
149  struct AVDES *des;
150  struct AVRC4 *rc4;
151  int num_qwords = len >> 3;
152  uint8_t *qwords = data;
153  uint64_t rc4buff[8] = { 0 };
154  uint64_t packetkey;
155  uint32_t ms_keys[12];
156  uint64_t ms_state;
157  int i;
158  if (len < 16) {
159  for (i = 0; i < len; i++)
160  data[i] ^= key[i];
161  return;
162  }
163  des = av_des_alloc();
164  rc4 = av_rc4_alloc();
165  if (!des || !rc4) {
166  av_freep(&des);
167  av_freep(&rc4);
168  return;
169  }
170 
171  av_rc4_init(rc4, key, 12 * 8, 1);
172  av_rc4_crypt(rc4, (uint8_t *)rc4buff, NULL, sizeof(rc4buff), NULL, 1);
173  multiswap_init((uint8_t *)rc4buff, ms_keys);
174 
175  packetkey = AV_RN64(&qwords[num_qwords * 8 - 8]);
176  packetkey ^= rc4buff[7];
177  av_des_init(des, key + 12, 64, 1);
178  av_des_crypt(des, (uint8_t *)&packetkey, (uint8_t *)&packetkey, 1, NULL, 1);
179  packetkey ^= rc4buff[6];
180 
181  av_rc4_init(rc4, (uint8_t *)&packetkey, 64, 1);
182  av_rc4_crypt(rc4, data, data, len, NULL, 1);
183 
184  ms_state = 0;
185  for (i = 0; i < num_qwords - 1; i++, qwords += 8)
186  ms_state = multiswap_enc(ms_keys, ms_state, AV_RL64(qwords));
187  multiswap_invert_keys(ms_keys);
188  packetkey = (packetkey << 32) | (packetkey >> 32);
189  packetkey = av_le2ne64(packetkey);
190  packetkey = multiswap_dec(ms_keys, ms_state, packetkey);
191  AV_WL64(qwords, packetkey);
192 
193  av_free(rc4);
194  av_free(des);
195 }
#define NULL
Definition: coverity.c:32
void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypts / decrypts using the DES algorithm.
Definition: des.c:322
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
static uint32_t multiswap_inv_step(const uint32_t keys[12], uint32_t v)
Definition: asfcrypt.c:87
const char * b
Definition: vf_curves.c:113
uint64_t_TMPL AV_RL64
Definition: bytestream.h:87
uint8_t
Definition: rc4.h:32
void av_rc4_crypt(AVRC4 *r, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypts / decrypts using the RC4 algorithm.
Definition: rc4.c:54
static uint32_t multiswap_step(const uint32_t keys[12], uint32_t v)
Definition: asfcrypt.c:75
static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12])
read keys from keybuf into keys
Definition: asfcrypt.c:54
#define AV_WL64(p, v)
Definition: intreadwrite.h:440
void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len)
Definition: asfcrypt.c:147
int av_des_init(AVDES *d, const uint8_t *key, int key_bits, av_unused int decrypt)
Definition: des.c:278
static void multiswap_invert_keys(uint32_t keys[12])
invert the keys so that encryption become decryption keys and the other way round.
Definition: asfcrypt.c:66
AVRC4 * av_rc4_alloc(void)
Allocate an AVRC4 context.
Definition: rc4.c:28
AVDES * av_des_alloc(void)
Allocate an AVDES context.
Definition: des.c:273
static uint64_t multiswap_enc(const uint32_t keys[12], uint64_t key, uint64_t data)
"MultiSwap" encryption
Definition: asfcrypt.c:107
#define av_le2ne64(x)
Definition: bswap.h:97
byte swapping routines
common internal and external API header
int av_rc4_init(AVRC4 *r, const uint8_t *key, int key_bits, int decrypt)
Initializes an AVRC4 context.
Definition: rc4.c:33
static double c[64]
static uint64_t multiswap_dec(const uint32_t keys[12], uint64_t key, uint64_t data)
"MultiSwap" decryption
Definition: asfcrypt.c:131
#define av_free(p)
int len
static uint8_t tmp[8]
Definition: des.c:38
#define AV_RN64(p)
Definition: intreadwrite.h:368
#define av_freep(p)
Definition: des.h:33
static uint32_t inverse(uint32_t v)
find multiplicative inverse modulo 2 ^ 32
Definition: asfcrypt.c:35
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:87