annotate ffmpeg/libavformat/asfcrypt.c @ 13:844d341cf643 tip

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