aacs.c 5.24 KB
Newer Older
cRTrn13's avatar
cRTrn13 committed
1 2

#include <stdio.h>
cRTrn13's avatar
cRTrn13 committed
3
#include <malloc.h>
cRTrn13's avatar
openssl  
cRTrn13 committed
4
#include <string.h>
cRTrn13's avatar
cRTrn13 committed
5 6

#include "aacs.h"
7
#include "crypto.h"
cRTrn13's avatar
cRTrn13 committed
8
#include "mmc.h"
cRTrn13's avatar
cRTrn13 committed
9
#include "../util/macro.h"
10
#include "../util/logging.h"
11
#include "../file/file.h"
cRTrn13's avatar
cRTrn13 committed
12

cRTrn13's avatar
cRTrn13 committed
13
int _calc_pk(AACS_KEYS *aacs);
cRTrn13's avatar
keyfile  
cRTrn13 committed
14
int _calc_mk(AACS_KEYS *aacs, const char *path);
cRTrn13's avatar
cRTrn13 committed
15 16
int _calc_vuk(AACS_KEYS *aacs, const char *path);
int _calc_uks(AACS_KEYS *aacs, const char *path);
cRTrn13's avatar
openssl  
cRTrn13 committed
17
int _validate_pk(uint8_t *pk, uint8_t *cvalue, uint8_t *uv, uint8_t *vd, uint8_t *mk);
cRTrn13's avatar
keyfile  
cRTrn13 committed
18
int _verify_ts(uint8_t *buf, size_t size);
19

20

cRTrn13's avatar
keyfile  
cRTrn13 committed
21 22
int _calc_mk(AACS_KEYS *aacs, const char *path)
{
23 24
    DEBUG(DBG_AACS, "Calculate media key...\n");

cRTrn13's avatar
keyfile  
cRTrn13 committed
25 26
    int a, num_uvs = 0;
    size_t len;
cRTrn13's avatar
cRTrn13 committed
27
    uint8_t *buf = NULL, *rec, *uvs, *key_pos, *pks;
cRTrn13's avatar
cRTrn13 committed
28
    uint16_t num_pks;
cRTrn13's avatar
keyfile  
cRTrn13 committed
29 30
    MKB *mkb = NULL;

31 32 33 34 35 36 37 38 39 40
    if ((mkb = mkb_open(path))) {
        DEBUG(DBG_AACS, "Get UVS...\n");
        uvs = mkb_subdiff_records(mkb, &len);
        rec = uvs;
        while (rec < uvs + len) {
            if (rec[0] & 0xc0)
                break;
            rec += 5;
            num_uvs++;
        }
cRTrn13's avatar
keyfile  
cRTrn13 committed
41

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
        DEBUG(DBG_AACS, "Get cvalues...\n");
        rec = mkb_cvalues(mkb, &len);
        if ((pks = configfile_record(aacs->kf, KF_PK_ARRAY, &num_pks, NULL))) {
            key_pos = pks;
            while (key_pos < pks + num_pks * 16) {
                memcpy(aacs->pk, key_pos, 16);
                DEBUG(DBG_AACS, "Trying processing key...\n");

                for (a = 0; a < num_uvs; a++) {
                    if (_validate_pk(aacs->pk, rec + a * 16, uvs + 1 + a * 5, mkb_mk_dv(mkb), aacs->mk)) {
                        mkb_close(mkb);
                        X_FREE(buf);
                        return 1;
                    }
                }

                key_pos += 16;
cRTrn13's avatar
keyfile  
cRTrn13 committed
59
            }
60
        }
cRTrn13's avatar
keyfile  
cRTrn13 committed
61

62 63
        mkb_close(mkb);
        X_FREE(buf);
cRTrn13's avatar
keyfile  
cRTrn13 committed
64 65 66 67
    }

    return 0;
}
68

cRTrn13's avatar
cRTrn13 committed
69
int _calc_vuk(AACS_KEYS *aacs, const char *path)
cRTrn13's avatar
openssl  
cRTrn13 committed
70 71 72 73
{
    int a;
    AES_KEY aes;
    uint8_t vid[16];
cRTrn13's avatar
cRTrn13 committed
74
    MMC* mmc = NULL;
cRTrn13's avatar
openssl  
cRTrn13 committed
75

cRTrn13's avatar
cRTrn13 committed
76
    if ((mmc = mmc_open(path,
cRTrn13's avatar
cRTrn13 committed
77 78 79 80
            configfile_record(aacs->kf, KF_HOST_PRIV_KEY, NULL, NULL),
            configfile_record(aacs->kf, KF_HOST_CERT, NULL, NULL),
            configfile_record(aacs->kf, KF_HOST_NONCE, NULL, NULL),
            configfile_record(aacs->kf, KF_HOST_KEY_POINT, NULL, NULL)))) {
cRTrn13's avatar
cRTrn13 committed
81 82 83
        if (mmc_read_vid(mmc)) {
            AES_set_decrypt_key(aacs->mk, 128, &aes);
            AES_decrypt(vid, aacs->vuk, &aes);
cRTrn13's avatar
openssl  
cRTrn13 committed
84 85

            for (a = 0; a < 16; a++) {
cRTrn13's avatar
cRTrn13 committed
86
                aacs->vuk[a] ^= vid[a];
cRTrn13's avatar
openssl  
cRTrn13 committed
87
            }
cRTrn13's avatar
cRTrn13 committed
88 89

            mmc_close(mmc);
cRTrn13's avatar
openssl  
cRTrn13 committed
90 91 92 93

            return 1;
        }

cRTrn13's avatar
cRTrn13 committed
94 95
        mmc_close(mmc);
    }
cRTrn13's avatar
openssl  
cRTrn13 committed
96 97 98 99

    return 0;
}

cRTrn13's avatar
cRTrn13 committed
100
int _calc_uks(AACS_KEYS *aacs, const char *path)
cRTrn13's avatar
openssl  
cRTrn13 committed
101 102
{
    AES_KEY aes;
103
    FILE_H *fp = NULL;
cRTrn13's avatar
openssl  
cRTrn13 committed
104 105
    unsigned char buf[16];
    char f_name[100];
106
    uint64_t f_pos;
cRTrn13's avatar
openssl  
cRTrn13 committed
107 108 109

    snprintf(f_name, 100, "/%s/AACS/Unit_Key_RO.inf", path);

110 111
    if ((fp = file_open(f_name, "rb"))) {
        file_read(fp, buf, 4);
cRTrn13's avatar
openssl  
cRTrn13 committed
112 113 114

        f_pos = MKINT_BE32(buf) + 48;

115 116
        file_seek(fp, f_pos, SEEK_SET);
        file_read(fp, buf, 16);
cRTrn13's avatar
openssl  
cRTrn13 committed
117

cRTrn13's avatar
cRTrn13 committed
118
        AES_set_decrypt_key(aacs->vuk, 128, &aes);
cRTrn13's avatar
openssl  
cRTrn13 committed
119 120
        AES_decrypt(buf, aacs->uks, &aes);

121
        file_close(fp);
cRTrn13's avatar
openssl  
cRTrn13 committed
122 123 124 125 126 127 128 129 130 131 132 133 134

        return 1;
    }

    return 0;
}

int _validate_pk(uint8_t *pk, uint8_t *cvalue, uint8_t *uv, uint8_t *vd, uint8_t *mk)
{
    int a;
    AES_KEY aes;
    uint8_t dec_vd[16];

135 136 137 138 139 140
    DEBUG(DBG_AACS, "Validate processing key %s...\n", print_hex(pk, 16));
    DEBUG(DBG_AACS, " Using:\n");
    DEBUG(DBG_AACS, "   UV: %s\n", print_hex(uv, 4));
    DEBUG(DBG_AACS, "   cvalue: %s\n", print_hex(cvalue, 16));
    DEBUG(DBG_AACS, "   Verification data: %s\n", print_hex(vd, 16));

cRTrn13's avatar
openssl  
cRTrn13 committed
141 142 143 144 145 146 147 148 149 150 151
    AES_set_decrypt_key(pk, 128, &aes);
    AES_decrypt(cvalue, mk, &aes);

    for (a = 0; a < 4; a++) {
        mk[a + 12] ^= uv[a];
    }

    AES_set_decrypt_key(mk, 128, &aes);
    AES_decrypt(vd, dec_vd, &aes);

    if (!memcmp(dec_vd, "\x01\x23\x45\x67\x89\xAB\xCD\xEF", 8)) {
152
        DEBUG(DBG_AACS, "Processing key is valid!\n");
cRTrn13's avatar
openssl  
cRTrn13 committed
153 154 155 156 157 158
        return 1;
    }

    return 0;
}

cRTrn13's avatar
cRTrn13 committed
159
AACS_KEYS *aacs_open(const char *path, const char *configfile_path)
cRTrn13's avatar
cRTrn13 committed
160
{
cRTrn13's avatar
cRTrn13 committed
161
    AACS_KEYS *aacs = malloc(sizeof(AACS_KEYS));
162

cRTrn13's avatar
cRTrn13 committed
163
    aacs->kf = NULL;
cRTrn13's avatar
cRTrn13 committed
164
    if ((aacs->kf = configfile_open(configfile_path))) {
165 166 167 168 169 170 171 172 173 174
        DEBUG(DBG_AACS, "Starting AACS waterfall...\n");
        //_calc_pk(aacs);
        if (_calc_mk(aacs, path)) {
            if (_calc_vuk(aacs, path)) {
                if (_calc_uks(aacs, path)) {
                    DEBUG(DBG_AACS, "AACS initialized (0x%08x)!\n", aacs);
                    return aacs;
                }
            }
        }
cRTrn13's avatar
cRTrn13 committed
175
    }
cRTrn13's avatar
cRTrn13 committed
176

cRTrn13's avatar
cRTrn13 committed
177
    return NULL;
cRTrn13's avatar
cRTrn13 committed
178 179
}

cRTrn13's avatar
cRTrn13 committed
180
void aacs_close(AACS_KEYS *aacs)
cRTrn13's avatar
cRTrn13 committed
181
{
cRTrn13's avatar
cRTrn13 committed
182
    configfile_close(aacs->kf);
cRTrn13's avatar
cRTrn13 committed
183

cRTrn13's avatar
cRTrn13 committed
184 185 186
    X_FREE(aacs);
}

cRTrn13's avatar
cRTrn13 committed
187
int aacs_decrypt_unit(AACS_KEYS *aacs, uint8_t *buf, uint32_t len)
188
{
cRTrn13's avatar
cRTrn13 committed
189 190 191 192 193 194 195
    if (len % 6144) {
        AES_cbc_encrypt(buf, buf, len, &aacs->aes, aacs->iv, 0);

        return 1;
    } else {
        int a;
        uint8_t key[16], iv[] = { 0x0b, 0xa0, 0xf8, 0xdd, 0xfe, 0xa6, 0x1f, 0xb3, 0xd8, 0xdf, 0x9f, 0x56, 0x6a, 0x05, 0x0f, 0x78 };
196

cRTrn13's avatar
cRTrn13 committed
197
        memcpy(aacs->iv, iv, 16);
198

cRTrn13's avatar
cRTrn13 committed
199 200
        AES_set_encrypt_key(aacs->uks, 128, &aacs->aes);
        AES_encrypt(buf, key, &aacs->aes);
201

cRTrn13's avatar
cRTrn13 committed
202 203 204
        for (a = 0; a < 16; a++) {
            key[a] ^= buf[a];
        }
cRTrn13's avatar
cRTrn13 committed
205

cRTrn13's avatar
cRTrn13 committed
206 207
        AES_set_decrypt_key(key, 128, &aacs->aes);
        AES_cbc_encrypt(buf + 16, buf + 16, 6144 - 16, &aacs->aes, iv, 0);
cRTrn13's avatar
cRTrn13 committed
208 209 210 211 212

        return 1;
    }

    return 0;
213
}