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 <stddef.h>
24 #include "libavutil/bswap.h"
25 #include "libavutil/des.h"
26 #include "libavutil/intreadwrite.h"
27 #include "libavutil/mem.h"
28 #include "libavutil/rc4.h"
29 #include "asfcrypt.h"
30 
31 /**
32  * @brief find multiplicative inverse modulo 2 ^ 32
33  * @param v number to invert, must be odd!
34  * @return number so that result * v = 1 (mod 2^32)
35  */
36 static uint32_t inverse(uint32_t v)
37 {
38  // v ^ 3 gives the inverse (mod 16), could also be implemented
39  // as table etc. (only lowest 4 bits matter!)
40  uint32_t inverse = v * v * v;
41  // uses a fixpoint-iteration that doubles the number
42  // of correct lowest bits each time
43  inverse *= 2 - v * inverse;
44  inverse *= 2 - v * inverse;
45  inverse *= 2 - v * inverse;
46  return inverse;
47 }
48 
49 /**
50  * @brief read keys from keybuf into keys
51  * @param keybuf buffer containing the keys
52  * @param keys output key array containing the keys for encryption in
53  * native endianness
54  */
55 static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12])
56 {
57  int i;
58  for (i = 0; i < 12; i++)
59  keys[i] = AV_RL32(keybuf + (i << 2)) | 1;
60 }
61 
62 /**
63  * @brief invert the keys so that encryption become decryption keys and
64  * the other way round.
65  * @param keys key array of ints to invert
66  */
67 static void multiswap_invert_keys(uint32_t keys[12])
68 {
69  int i;
70  for (i = 0; i < 5; i++)
71  keys[i] = inverse(keys[i]);
72  for (i = 6; i < 11; i++)
73  keys[i] = inverse(keys[i]);
74 }
75 
76 static uint32_t multiswap_step(const uint32_t keys[6], uint32_t v)
77 {
78  int i;
79  v *= keys[0];
80  for (i = 1; i < 5; i++) {
81  v = (v >> 16) | (v << 16);
82  v *= keys[i];
83  }
84  v += keys[5];
85  return v;
86 }
87 
88 static uint32_t multiswap_inv_step(const uint32_t keys[6], uint32_t v)
89 {
90  int i;
91  v -= keys[5];
92  for (i = 4; i > 0; i--) {
93  v *= keys[i];
94  v = (v >> 16) | (v << 16);
95  }
96  v *= keys[0];
97  return v;
98 }
99 
100 /**
101  * @brief "MultiSwap" encryption
102  * @param keys 32 bit numbers in machine endianness,
103  * 0-4 and 6-10 must be inverted from decryption
104  * @param key another key, this one must be the same for the decryption
105  * @param data data to encrypt
106  * @return encrypted data
107  */
108 static uint64_t multiswap_enc(const uint32_t keys[12],
109  uint64_t key, uint64_t data)
110 {
111  uint32_t a = data;
112  uint32_t b = data >> 32;
113  uint32_t c;
114  uint32_t tmp;
115  a += key;
116  tmp = multiswap_step(keys, a);
117  b += tmp;
118  c = (key >> 32) + tmp;
119  tmp = multiswap_step(keys + 6, b);
120  c += tmp;
121  return ((uint64_t)c << 32) | tmp;
122 }
123 
124 /**
125  * @brief "MultiSwap" decryption
126  * @param keys 32 bit numbers in machine endianness,
127  * 0-4 and 6-10 must be inverted from encryption
128  * @param key another key, this one must be the same as for the encryption
129  * @param data data to decrypt
130  * @return decrypted data
131  */
132 static uint64_t multiswap_dec(const uint32_t keys[12],
133  uint64_t key, uint64_t data)
134 {
135  uint32_t a;
136  uint32_t b;
137  uint32_t c = data >> 32;
138  uint32_t tmp = data;
139  c -= tmp;
140  b = multiswap_inv_step(keys + 6, tmp);
141  tmp = c - (key >> 32);
142  b -= tmp;
143  a = multiswap_inv_step(keys, tmp);
144  a -= key;
145  return ((uint64_t)b << 32) | a;
146 }
147 
148 void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len)
149 {
150  struct AVDES *des;
151  struct AVRC4 *rc4;
152  int num_qwords = len >> 3;
153  uint8_t *qwords = data;
154  uint64_t rc4buff[8] = { 0 };
155  uint64_t packetkey;
156  uint32_t ms_keys[12];
157  uint64_t ms_state;
158  int i;
159  if (len < 16) {
160  for (i = 0; i < len; i++)
161  data[i] ^= key[i];
162  return;
163  }
164  des = av_des_alloc();
165  rc4 = av_rc4_alloc();
166  if (!des || !rc4) {
167  av_freep(&des);
168  av_freep(&rc4);
169  return;
170  }
171 
172  av_rc4_init(rc4, key, 12 * 8, 1);
173  av_rc4_crypt(rc4, (uint8_t *)rc4buff, NULL, sizeof(rc4buff), NULL, 1);
174  multiswap_init((uint8_t *)rc4buff, ms_keys);
175 
176  packetkey = AV_RN64(&qwords[num_qwords * 8 - 8]);
177  packetkey ^= rc4buff[7];
178  av_des_init(des, key + 12, 64, 1);
179  av_des_crypt(des, (uint8_t *)&packetkey, (uint8_t *)&packetkey, 1, NULL, 1);
180  packetkey ^= rc4buff[6];
181 
182  av_rc4_init(rc4, (uint8_t *)&packetkey, 64, 1);
183  av_rc4_crypt(rc4, data, data, len, NULL, 1);
184 
185  ms_state = 0;
186  for (i = 0; i < num_qwords - 1; i++, qwords += 8)
187  ms_state = multiswap_enc(ms_keys, ms_state, AV_RL64(qwords));
188  multiswap_invert_keys(ms_keys);
189  packetkey = (packetkey << 32) | (packetkey >> 32);
190  packetkey = av_le2ne64(packetkey);
191  packetkey = multiswap_dec(ms_keys, ms_state, packetkey);
192  AV_WL64(qwords, packetkey);
193 
194  av_free(rc4);
195  av_free(des);
196 }
av_des_init
int av_des_init(AVDES *d, const uint8_t *key, int key_bits, av_unused int decrypt)
Definition: des.c:280
AV_RL64
uint64_t_TMPL AV_RL64
Definition: bytestream.h:91
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:324
AVRC4
Definition: rc4.h:32
AV_RN64
#define AV_RN64(p)
Definition: intreadwrite.h:366
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
b
#define b
Definition: input.c:41
data
const char data[16]
Definition: mxf.c:148
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:67
asfcrypt.h
multiswap_enc
static uint64_t multiswap_enc(const uint32_t keys[12], uint64_t key, uint64_t data)
"MultiSwap" encryption
Definition: asfcrypt.c:108
intreadwrite.h
key
const char * key
Definition: hwcontext_opencl.c:174
multiswap_dec
static uint64_t multiswap_dec(const uint32_t keys[12], uint64_t key, uint64_t data)
"MultiSwap" decryption
Definition: asfcrypt.c:132
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:55
multiswap_step
static uint32_t multiswap_step(const uint32_t keys[6], uint32_t v)
Definition: asfcrypt.c:76
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:99
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:438
av_rc4_alloc
AVRC4 * av_rc4_alloc(void)
Allocate an AVRC4 context.
Definition: rc4.c:29
av_des_alloc
AVDES * av_des_alloc(void)
Allocate an AVDES context.
Definition: des.c:275
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
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:55
len
int len
Definition: vorbis_enc_data.h:426
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:34
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
multiswap_inv_step
static uint32_t multiswap_inv_step(const uint32_t keys[6], uint32_t v)
Definition: asfcrypt.c:88
mem.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
inverse
static uint32_t inverse(uint32_t v)
find multiplicative inverse modulo 2 ^ 32
Definition: asfcrypt.c:36
rc4.h
ff_asfcrypt_dec
void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len)
Definition: asfcrypt.c:148