-
Notifications
You must be signed in to change notification settings - Fork 1
/
Decoder-ECM.cpp
executable file
·91 lines (75 loc) · 1.87 KB
/
Decoder-ECM.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <string.h>
#include "Global.h"
#include "Decoder.h"
#include "Crypto.h"
#include "Keyset.h"
typedef struct
{
// 0x00
u8 ProtocolNumber;
// 0x01
u8 BroadcasterGroupID;
// 0x02
u8 WorkKeyID;
// 0x03
u8 ScramblingKeyOdd[8];
// 0x0b
u8 ScramblingKeyEven[8];
// 0x13
u8 ProgramType;
// 0x14
u8 Date[2];
// 0x16
u8 Time[3];
// 0x19
u8 RecordingControl;
} ECM_t;
typedef u8 CRC32_t[4];
typedef u8 MAC_t[4];
static s32
DecryptECM (const ECM_t * ECM, u32 Size, u8 * Output, u8 * Key)
{
if (ECM == NULL || Size < sizeof (ECM_t) + sizeof (MAC_t))
return -1;
//BCAS::Keyset::GetKey (ECM->BroadcasterGroupID, ECM->WorkKeyID, Key);
s32 rc = BCAS::Keyset::GetKey (ECM->BroadcasterGroupID, ECM->WorkKeyID, Key);
if (rc < 0)
return rc;
*Output++ = ECM->ProtocolNumber;
*Output++ = ECM->BroadcasterGroupID;
*Output++ = ECM->WorkKeyID;
BCAS::Crypto::Transform (ECM->ProtocolNumber, Key, ECM->ScramblingKeyOdd,
Size - 3, Output, true);
return 0;
}
s32
BCAS::Decoder::DecodeECM (const u8 * Payload, u32 Size, u8 * Keys, u8 * Nanos)
{
u8
Plaintext[256];
u8
Key[8];
u8
MAC[4];
if (Payload == NULL || Size < sizeof (ECM_t) + sizeof (MAC_t))
return -1;
const ECM_t *
ECM = reinterpret_cast < const
ECM_t * >(Payload);
if (DecryptECM (ECM, Size, Plaintext, Key) < 0)
{
if (Keys != NULL)
memset (Keys, 0, 16);
return -2;
}
Size -= sizeof (MAC_t);
BCAS::Crypto::GenerateMAC (ECM->ProtocolNumber, Key, Plaintext, Size, MAC);
if (memcmp (MAC, Plaintext + Size, sizeof (MAC_t)))
return -3;
ECM = reinterpret_cast < const ECM_t *>(Plaintext);
if (Keys != NULL)
memcpy (Keys, ECM->ScramblingKeyOdd, 16);
if (Nanos != NULL)
memcpy (Nanos, ECM + 1, Size - sizeof (ECM_t));
return 0;
}