FFmpeg
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 }
av_des_init
int av_des_init(AVDES *d, const uint8_t *key, int key_bits, av_unused int decrypt)
Definition: des.c:278
AV_RL64
uint64_t_TMPL AV_RL64
Definition: bytestream.h:87
av_des_crypt
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
AVRC4
Definition: rc4.h:32
AV_RN64
#define AV_RN64(p)
Definition: intreadwrite.h:368
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
b
#define b
Definition: input.c:41
data
const char data[16]
Definition: mxf.c:91
multiswap_invert_keys
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
asfcrypt.h
multiswap_inv_step
static uint32_t multiswap_inv_step(const uint32_t keys[12], uint32_t v)
Definition: asfcrypt.c:87
multiswap_enc
static uint64_t multiswap_enc(const uint32_t keys[12], uint64_t key, uint64_t data)
"MultiSwap" encryption
Definition: asfcrypt.c:107
intreadwrite.h
key
const char * key
Definition: hwcontext_opencl.c:168
multiswap_dec
static uint64_t multiswap_dec(const uint32_t keys[12], uint64_t key, uint64_t data)
"MultiSwap" decryption
Definition: asfcrypt.c:131
NULL
#define NULL
Definition: coverity.c:32
multiswap_init
static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12])
read keys from keybuf into keys
Definition: asfcrypt.c:54
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
av_le2ne64
#define av_le2ne64(x)
Definition: bswap.h:97
des.h
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
AV_WL64
#define AV_WL64(p, v)
Definition: intreadwrite.h:440
av_rc4_alloc
AVRC4 * av_rc4_alloc(void)
Allocate an AVRC4 context.
Definition: rc4.c:28
av_des_alloc
AVDES * av_des_alloc(void)
Allocate an AVDES context.
Definition: des.c:273
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
av_rc4_crypt
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
common.h
uint8_t
uint8_t
Definition: audio_convert.c:194
len
int len
Definition: vorbis_enc_data.h:452
AVDES
Definition: des.h:33
bswap.h
av_rc4_init
int av_rc4_init(AVRC4 *r, const uint8_t *key, int key_bits, int decrypt)
Initializes an AVRC4 context.
Definition: rc4.c:33
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:88
multiswap_step
static uint32_t multiswap_step(const uint32_t keys[12], uint32_t v)
Definition: asfcrypt.c:75
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
inverse
static uint32_t inverse(uint32_t v)
find multiplicative inverse modulo 2 ^ 32
Definition: asfcrypt.c:35
rc4.h
ff_asfcrypt_dec
void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len)
Definition: asfcrypt.c:147