static int _libaacs_init(BD_DEC *dec, struct dec_dev *dev, BD_ENC_INFO *i, const char *keyfile_path) { int result; const uint8_t *disc_id; if (!dec->aacs) { return 0; } result = libaacs_open(dec->aacs, dev->device, dev->file_open_vfs_handle, (void*)dev->pf_file_open_vfs, keyfile_path); i->aacs_error_code = result; i->aacs_handled = !result; i->aacs_mkbv = libaacs_get_mkbv(dec->aacs); disc_id = libaacs_get_aacs_data(dec->aacs, BD_AACS_DISC_ID); if (disc_id) { memcpy(i->disc_id, disc_id, 20); } if (result) { BD_DEBUG(DBG_BLURAY | DBG_CRIT, "aacs_open() failed: %d!\n", result); libaacs_unload(&dec->aacs); return 0; } BD_DEBUG(DBG_BLURAY, "Opened libaacs\n"); return 1; }
BD_AACS *libaacs_load(void) { BD_AACS *p = calloc(1, sizeof(BD_AACS)); p->h_libaacs = _open_libaacs(); if (!p->h_libaacs) { X_FREE(p); return NULL; } BD_DEBUG(DBG_BLURAY, "Loading aacs library (%p)\n", p->h_libaacs); *(void **)(&p->decrypt_unit) = dl_dlsym(p->h_libaacs, "aacs_decrypt_unit"); *(void **)(&p->get_vid) = dl_dlsym(p->h_libaacs, "aacs_get_vid"); *(void **)(&p->get_pmsn) = dl_dlsym(p->h_libaacs, "aacs_get_pmsn"); *(void **)(&p->get_device_binding_id) = dl_dlsym(p->h_libaacs, "aacs_get_device_binding_id"); *(void **)(&p->get_device_nonce) = dl_dlsym(p->h_libaacs, "aacs_get_device_nonce"); if (!p->decrypt_unit) { BD_DEBUG(DBG_BLURAY | DBG_CRIT, "libaacs dlsym failed! (%p)\n", p->h_libaacs); libaacs_unload(&p); return NULL; } BD_DEBUG(DBG_BLURAY, "Loaded libaacs (%p)\n", p->h_libaacs); if (file_open != file_open_default()) { BD_DEBUG(DBG_BLURAY, "Registering libaacs filesystem handler %p (%p)\n", (void *)(intptr_t)file_open, p->h_libaacs); DL_CALL(p->h_libaacs, aacs_register_file, file_open); } return p; }
static BD_AACS *_load(int impl_id) { BD_AACS *p = calloc(1, sizeof(BD_AACS)); if (!p) { return NULL; } p->impl_id = impl_id; p->h_libaacs = _open_libaacs(&p->impl_id); if (!p->h_libaacs) { X_FREE(p); return NULL; } BD_DEBUG(DBG_BLURAY, "Loading aacs library (%p)\n", p->h_libaacs); *(void **)(&p->decrypt_unit) = dl_dlsym(p->h_libaacs, "aacs_decrypt_unit"); *(void **)(&p->decrypt_bus) = dl_dlsym(p->h_libaacs, "aacs_decrypt_bus"); if (!p->decrypt_unit) { BD_DEBUG(DBG_BLURAY | DBG_CRIT, "libaacs dlsym failed! (%p)\n", p->h_libaacs); libaacs_unload(&p); return NULL; } BD_DEBUG(DBG_BLURAY, "Loaded libaacs (%p)\n", p->h_libaacs); if (file_open != file_open_default()) { BD_DEBUG(DBG_BLURAY, "Registering libaacs filesystem handler %p (%p)\n", (void *)(intptr_t)file_open, p->h_libaacs); DL_CALL(p->h_libaacs, aacs_register_file, file_open); } return p; }
void dec_close(BD_DEC **pp) { if (pp && *pp) { BD_DEC *p = *pp; libaacs_unload(&p->aacs); libbdplus_unload(&p->bdplus); X_FREE(*pp); } }
int libaacs_open(BD_AACS *p, const char *device, void *file_open_handle, void *file_open_fp, const char *keyfile_path) { int error_code = 0; fptr_p_void open; fptr_p_void open2; fptr_p_void init; fptr_int open_device; fptr_int aacs_get_mkb_version; fptr_p_void aacs_get_disc_id; _libaacs_close(p); *(void **)(&open) = dl_dlsym(p->h_libaacs, "aacs_open"); *(void **)(&open2) = dl_dlsym(p->h_libaacs, "aacs_open2"); *(void **)(&init) = dl_dlsym(p->h_libaacs, "aacs_init"); *(void **)(&aacs_get_mkb_version) = dl_dlsym(p->h_libaacs, "aacs_get_mkb_version"); *(void **)(&aacs_get_disc_id) = dl_dlsym(p->h_libaacs, "aacs_get_disc_id"); *(void **)(&open_device) = dl_dlsym(p->h_libaacs, "aacs_open_device"); if (init && open_device) { p->aacs = init(); DL_CALL(p->h_libaacs, aacs_set_fopen, p->aacs, file_open_handle, file_open_fp); error_code = open_device(p->aacs, device, keyfile_path); } else if (open2) { BD_DEBUG(DBG_BLURAY, "Using old aacs_open2(), no UDF support available\n"); p->aacs = open2(device, keyfile_path, &error_code); /* libmmbd needs dev: for devices */ if (!p->aacs && p->impl_id == IMPL_LIBMMBD && !strncmp(device, "/dev/", 5)) { char *tmp_device = str_printf("dev:%s", device); if (tmp_device) { p->aacs = open2(tmp_device, keyfile_path, &error_code); X_FREE(tmp_device); } } } else if (open) { BD_DEBUG(DBG_BLURAY, "Using old aacs_open(), no verbose error reporting available\n"); p->aacs = open(device, keyfile_path); } else { BD_DEBUG(DBG_BLURAY, "aacs_open() not found\n"); } if (error_code) { /* failed. try next aacs implementation if available. */ BD_AACS *p2 = _load(p->impl_id + 1); if (p2) { if (!libaacs_open(p2, device, file_open_handle, file_open_fp, keyfile_path)) { /* succeed - swap implementations */ _unload(p); *p = *p2; X_FREE(p2); return 0; } /* failed - report original errors */ libaacs_unload(&p2); } } if (p->aacs) { if (aacs_get_mkb_version) { p->mkbv = aacs_get_mkb_version(p->aacs); } if (aacs_get_disc_id) { p->disc_id = (const uint8_t *)aacs_get_disc_id(p->aacs); } return error_code; } return error_code ? error_code : 1; }