Commit edd91c94 authored by Slava Monich's avatar Slava Monich

Merge branch 'auth' into 'master'

Implement org.ofono.SimAuthentication interface

See merge request mer-core/ofono!283
parents 1116ca24 af0ab142
/*
* oFono - Open Source Telephony - RIL-based devices
*
* Copyright (C) 2015-2020 Jolla Ltd.
* Copyright (C) 2015-2021 Jolla Ltd.
* Copyright (C) 2019 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
......@@ -340,6 +340,7 @@ static void ril_modem_post_sim(struct ofono_modem *modem)
if (md->modem.config.enable_cbs) {
ofono_cbs_create(modem, 0, RILMODEM_DRIVER, md);
}
ofono_sim_auth_create(modem);
}
static void ril_modem_post_online(struct ofono_modem *modem)
......
This diff is collapsed.
......@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -210,6 +211,10 @@ struct ofono_sim_driver {
void (*logical_access)(struct ofono_sim *sim, int session_id,
const unsigned char *pdu, unsigned int len,
ofono_sim_logical_access_cb_t cb, void *data);
/* Since mer/1.23+git28 */
void (*open_channel2)(struct ofono_sim *sim, const unsigned char *aid,
unsigned int len, ofono_sim_open_channel_cb_t cb,
void *data);
};
int ofono_sim_driver_register(const struct ofono_sim_driver *d);
......
......@@ -3,7 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2019 Jolla Ltd.
* Copyright (C) 2015-2021 Jolla Ltd.
* Copyright (C) 2019 Open Mobile Platform LLC.
*
* This program is free software; you can redistribute it and/or modify
......@@ -388,6 +388,7 @@ unsigned short __ofono_sms_get_next_ref(struct ofono_sms *sms);
#include <ofono/sim.h>
struct sim_aid;
struct ofono_sim_aid_session;
enum sim_app_type;
......@@ -426,7 +427,7 @@ void __ofono_sim_remove_session_watch(struct ofono_sim_aid_session *session,
unsigned int id);
struct ofono_sim_aid_session *__ofono_sim_get_session_by_aid(
struct ofono_sim *sim, unsigned char *aid);
struct ofono_sim *sim, const struct sim_aid *aid);
struct ofono_sim_aid_session *__ofono_sim_get_session_by_type(
struct ofono_sim *sim, enum sim_app_type type);
......@@ -436,7 +437,7 @@ int __ofono_sim_session_get_id(struct ofono_sim_aid_session *session);
enum sim_app_type __ofono_sim_session_get_type(
struct ofono_sim_aid_session *session);
unsigned char *__ofono_sim_session_get_aid(
const struct sim_aid *__ofono_sim_session_get_aid(
struct ofono_sim_aid_session *session);
const char *__ofono_sim_get_impi(struct ofono_sim *sim);
......
......@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -62,7 +63,7 @@ struct auth_request {
};
struct aid_object {
uint8_t aid[16];
struct sim_aid aid;
char *path;
enum sim_app_type type;
};
......@@ -82,7 +83,7 @@ struct ofono_sim_auth {
/*
* Find an application by path. 'path' should be a DBusMessage object path.
*/
static uint8_t *find_aid_by_path(GSList *aid_objects,
static const struct aid_object *find_aid_by_path(GSList *aid_objects,
const char *path)
{
GSList *iter = aid_objects;
......@@ -91,7 +92,7 @@ static uint8_t *find_aid_by_path(GSList *aid_objects,
struct aid_object *obj = iter->data;
if (!strcmp(path, obj->path))
return obj->aid;
return obj;
iter = g_slist_next(iter);
}
......@@ -208,14 +209,10 @@ static void handle_umts(struct ofono_sim_auth *sa, const uint8_t *resp,
DBusMessage *reply = NULL;
DBusMessageIter iter;
DBusMessageIter dict;
const uint8_t *res = NULL;
const uint8_t *ck = NULL;
const uint8_t *ik = NULL;
const uint8_t *auts = NULL;
const uint8_t *kc = NULL;
struct data_block res, ck, ik, auts, sres, kc;
if (!sim_parse_umts_authenticate(resp, len, &res, &ck, &ik,
&auts, &kc))
&auts, &sres, &kc))
goto umts_end;
reply = dbus_message_new_method_return(sa->pending->msg);
......@@ -225,15 +222,23 @@ static void handle_umts(struct ofono_sim_auth *sa, const uint8_t *resp,
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
"{say}", &dict);
if (auts) {
append_dict_byte_array(&dict, "AUTS", auts, 14);
} else {
append_dict_byte_array(&dict, "RES", res, 8);
append_dict_byte_array(&dict, "CK", ck, 16);
append_dict_byte_array(&dict, "IK", ik, 16);
if (kc)
append_dict_byte_array(&dict, "Kc", kc, 8);
}
if (auts.data)
append_dict_byte_array(&dict, "AUTS", auts.data, auts.len);
if (sres.data)
append_dict_byte_array(&dict, "SRES", sres.data, sres.len);
if (res.data)
append_dict_byte_array(&dict, "RES", res.data, res.len);
if (ck.data)
append_dict_byte_array(&dict, "CK", ck.data, ck.len);
if (ik.data)
append_dict_byte_array(&dict, "IK", ik.data, ik.len);
if (kc.data)
append_dict_byte_array(&dict, "Kc", kc.data, kc.len);
dbus_message_iter_close_container(&iter, &dict);
......@@ -380,7 +385,7 @@ static DBusMessage *usim_gsm_authenticate(DBusConnection *conn,
struct ofono_sim_auth *sa = data;
DBusMessageIter iter;
DBusMessageIter array;
uint8_t *aid;
const struct aid_object *obj;
if (sa->pending)
return __ofono_error_busy(msg);
......@@ -420,13 +425,20 @@ static DBusMessage *usim_gsm_authenticate(DBusConnection *conn,
/*
* retrieve session from SIM
*/
aid = find_aid_by_path(sa->aid_objects, dbus_message_get_path(msg));
sa->pending->session = __ofono_sim_get_session_by_aid(sa->sim, aid);
obj = find_aid_by_path(sa->aid_objects, dbus_message_get_path(msg));
sa->pending->session = __ofono_sim_get_session_by_aid(sa->sim,
&obj->aid);
sa->pending->msg = dbus_message_ref(msg);
sa->pending->watch_id = __ofono_sim_add_session_watch(
sa->pending->session, get_session_cb, sa, NULL);
return NULL;
if (!sa->pending->watch_id) {
g_free(sa->pending);
sa->pending = NULL;
return __ofono_error_not_supported(msg);
}
return NULL;
format_error:
g_free(sa->pending);
......@@ -442,7 +454,7 @@ static DBusMessage *umts_common(DBusConnection *conn, DBusMessage *msg,
uint32_t rlen;
uint32_t alen;
struct ofono_sim_auth *sa = data;
uint8_t *aid;
const struct aid_object *obj;
if (sa->pending)
return __ofono_error_busy(msg);
......@@ -467,12 +479,18 @@ static DBusMessage *umts_common(DBusConnection *conn, DBusMessage *msg,
/*
* retrieve session from SIM
*/
aid = find_aid_by_path(sa->aid_objects, dbus_message_get_path(msg));
sa->pending->session = __ofono_sim_get_session_by_aid(sa->sim, aid);
obj = find_aid_by_path(sa->aid_objects, dbus_message_get_path(msg));
sa->pending->session = __ofono_sim_get_session_by_aid(sa->sim,
&obj->aid);
sa->pending->watch_id = __ofono_sim_add_session_watch(
sa->pending->session, get_session_cb, sa, NULL);
if (!sa->pending->watch_id) {
g_free(sa->pending);
sa->pending = NULL;
return __ofono_error_not_supported(msg);
}
return NULL;
}
......@@ -702,14 +720,15 @@ static void sim_auth_register(struct ofono_sim_auth *sa)
ret = sprintf(new->path, "%s/", path);
encode_hex_own_buf(r->aid, 16, 0, new->path + ret);
encode_hex_own_buf(r->aid.aid, r->aid.len, 0,
new->path + ret);
g_dbus_register_interface(conn, new->path,
OFONO_USIM_APPLICATION_INTERFACE,
sim_auth_usim_app, NULL, NULL,
sa, NULL);
memcpy(new->aid, r->aid, 16);
new->aid = r->aid;
break;
case SIM_APP_TYPE_ISIM:
......@@ -717,14 +736,15 @@ static void sim_auth_register(struct ofono_sim_auth *sa)
ret = sprintf(new->path, "%s/", path);
encode_hex_own_buf(r->aid, 16, 0, new->path + ret);
encode_hex_own_buf(r->aid.aid, r->aid.len, 0,
new->path + ret);
g_dbus_register_interface(conn, new->path,
OFONO_ISIM_APPLICATION_INTERFACE,
sim_auth_isim_app, NULL, NULL,
sa, NULL);
memcpy(new->aid, r->aid, 16);
new->aid = r->aid;
break;
default:
......
......@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -2441,7 +2442,7 @@ struct ofono_sim_context *ofono_sim_context_create_isim(
if (session->record->type == SIM_APP_TYPE_ISIM) {
return sim_fs_context_new_with_aid(sim->simfs_isim,
session->record->aid);
&session->record->aid);
}
iter = g_slist_next(iter);
......@@ -3667,6 +3668,26 @@ const char *__ofono_sim_get_impi(struct ofono_sim *sim)
static void open_channel_cb(const struct ofono_error *error, int session_id,
void *data);
static gboolean open_channel(struct ofono_sim_aid_session *session)
{
struct ofono_sim *sim = session->sim;
const struct ofono_sim_driver *driver = sim->driver;
const struct sim_aid *aid = &session->record->aid;
if (driver->open_channel2) {
driver->open_channel2(sim, aid->aid, aid->len, open_channel_cb,
session);
return TRUE;
}
if (driver->open_channel && aid->len == 16) {
driver->open_channel(sim, aid->aid, open_channel_cb, session);
return TRUE;
}
return FALSE;
}
static void close_channel_cb(const struct ofono_error *error, void *data)
{
struct ofono_sim_aid_session *session = data;
......@@ -3680,10 +3701,8 @@ static void close_channel_cb(const struct ofono_error *error, void *data)
* An atom requested to open during a close, we can re-open
* here.
*/
session->sim->driver->open_channel(session->sim,
session->record->aid, open_channel_cb,
session);
return;
if (open_channel(session))
return;
}
session->state = SESSION_STATE_INACTIVE;
......@@ -3758,10 +3777,12 @@ unsigned int __ofono_sim_add_session_watch(
* If the session is inactive and there are no watchers, open
* a new session.
*/
session->state = SESSION_STATE_OPENING;
session->sim->driver->open_channel(session->sim,
session->record->aid, open_channel_cb,
session);
if (open_channel(session)) {
session->state = SESSION_STATE_OPENING;
} else {
g_free(item);
return 0;
}
} else if (session->state == SESSION_STATE_OPEN) {
/*
* Session is already open and available, just call the
......@@ -3794,14 +3815,15 @@ void __ofono_sim_remove_session_watch(struct ofono_sim_aid_session *session,
}
struct ofono_sim_aid_session *__ofono_sim_get_session_by_aid(
struct ofono_sim *sim, unsigned char *aid)
struct ofono_sim *sim, const struct sim_aid *aid)
{
GSList *iter = sim->aid_sessions;
while (iter) {
struct ofono_sim_aid_session *session = iter->data;
if (!memcmp(session->record->aid, aid, 16))
if (session->record->aid.len == aid->len &&
!memcmp(session->record->aid.aid, aid, aid->len))
return session;
iter = g_slist_next(iter);
......@@ -3838,10 +3860,10 @@ enum sim_app_type __ofono_sim_session_get_type(
return session->record->type;
}
unsigned char *__ofono_sim_session_get_aid(
const struct sim_aid *__ofono_sim_session_get_aid(
struct ofono_sim_aid_session *session)
{
return session->record->aid;
return &session->record->aid;
}
GSList *__ofono_sim_get_aid_list(struct ofono_sim *sim)
......
......@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -164,7 +165,7 @@ struct ofono_sim_context *sim_fs_context_new(struct sim_fs *fs)
}
struct ofono_sim_context *sim_fs_context_new_with_aid(struct sim_fs *fs,
unsigned char *aid)
const struct sim_aid *aid)
{
struct ofono_sim_context *context = sim_fs_context_new(fs);
......
......@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -20,6 +21,7 @@
*/
struct sim_fs;
struct sim_aid;
typedef void (*sim_fs_read_info_cb_t)(int ok, unsigned char file_status,
int total_length, int record_length,
......@@ -30,7 +32,7 @@ struct sim_fs *sim_fs_new(struct ofono_sim *sim,
struct ofono_sim_context *sim_fs_context_new(struct sim_fs *fs);
struct ofono_sim_context *sim_fs_context_new_with_aid(struct sim_fs *fs,
unsigned char *aid);
const struct sim_aid *aid);
unsigned int sim_fs_file_watch_add(struct ofono_sim_context *context,
int id, ofono_sim_file_changed_cb_t cb,
......
......@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -1572,20 +1573,17 @@ GSList *sim_parse_app_template_entries(const unsigned char *buffer, int len)
/* Find all the application entries */
while ((dataobj = ber_tlv_find_by_tag(buffer, 0x61, len,
&dataobj_len)) != NULL) {
struct sim_app_record app;
struct sim_app_record *app;
const unsigned char *aid, *label;
int label_len;
int label_len, aid_len;
char *app_label;
/* Find the aid (mandatory) */
aid = ber_tlv_find_by_tag(dataobj, 0x4f, dataobj_len,
&app.aid_len);
if (!aid || app.aid_len < 0x01 || app.aid_len > 0x10)
&aid_len);
if (!aid || aid_len < 0x01 || aid_len > 0x10)
goto error;
memcpy(app.aid, aid, app.aid_len);
app.type = (app.aid[5] << 8) | app.aid[6];
/* Find the label (optional) */
label = ber_tlv_find_by_tag(dataobj, 0x50, dataobj_len,
&label_len);
......@@ -1594,14 +1592,21 @@ GSList *sim_parse_app_template_entries(const unsigned char *buffer, int len)
* Label field uses the extra complicated
* encoding in 102.221 Annex A
*/
app.label = sim_string_to_utf8(label, label_len);
app_label = sim_string_to_utf8(label, label_len);
if (app.label == NULL)
if (app_label == NULL)
goto error;
} else
app.label = NULL;
app_label = NULL;
app = g_new0(struct sim_app_record, 1);
ret = g_slist_prepend(ret, g_memdup(&app, sizeof(app)));
memcpy(app->aid.aid, aid, aid_len);
app->aid.len = aid_len;
app->label = app_label;
app->type = (aid[5] << 8) | aid[6];
ret = g_slist_prepend(ret, app);
len -= (dataobj - buffer) + dataobj_len;
buffer = dataobj + dataobj_len;
......@@ -1667,67 +1672,135 @@ int sim_build_gsm_authenticate(unsigned char *buffer, int len,
return build_authenticate(buffer, rand, NULL);
}
gboolean sim_parse_umts_authenticate(const unsigned char *buffer,
int len, const unsigned char **res, const unsigned char **ck,
const unsigned char **ik, const unsigned char **auts,
const unsigned char **kc)
gboolean sim_parse_umts_authenticate(const unsigned char *buffer, int len,
struct data_block *res, struct data_block *ck,
struct data_block *ik, struct data_block *auts,
struct data_block *sres, struct data_block *kc)
{
if (len < 16 || !buffer)
const unsigned char *ptr = buffer;
const unsigned char *end = ptr + len;
unsigned int l;
if (!buffer || len < 2)
return FALSE;
switch (buffer[0]) {
memset(res, 0, sizeof(*res));
memset(ck, 0, sizeof(*ck));
memset(ik, 0, sizeof(*ik));
memset(kc, 0, sizeof(*kc));
memset(auts, 0, sizeof(*auts));
memset(sres, 0, sizeof(*sres));
/*
* TS 31.102
* 7.1.2.1 GSM/3G security context
*/
switch (*ptr++) {
case 0xdb:
/* 'DB' + '08' + RES(16) + '10' + CK(32) + '10' + IK(32) = 43 */
if (len < 43)
goto umts_end;
/*
* Response parameters/data, case 1, 3G security context,
* command successful:
*
* "Successful 3G authentication" tag = 'DB'
* 'DB' + L3 + RES(L3) + L4 + CK(L4) + L5 + IK(L5) + 8 + Kc(8)
*/
l = *ptr++; /* L3 */
if ((ptr + l) > end)
return FALSE;
/* success */
if (buffer[1] != 0x08)
goto umts_end;
res->data = ptr;
res->len = l;
ptr += l;
*res = buffer + 2;
if (ptr == end)
return FALSE;
if (buffer[10] != 0x10)
goto umts_end;
l = *ptr++; /* L4 */
if ((ptr + l) > end)
return FALSE;
*ck = buffer + 11;
ck->data = ptr;
ck->len = l;
ptr += l;
if (buffer[27] != 0x10)
goto umts_end;
if (ptr == end)
return FALSE;
*ik = buffer + 28;
l = *ptr++; /* L5 */
if ((ptr + l) > end)
return FALSE;
if (len >= 53 && kc) {
if (buffer[44] != 0x08)
goto umts_end;
ik->data = ptr;
ik->len = l;
ptr += l;
*kc = buffer + 45;
} else {
*kc = NULL;
if (ptr < end) {
l = *ptr++;
if (l != 8 || (ptr + l) != end)
return FALSE;
kc->data = ptr;
kc->len = l;
ptr += l;
}
*auts = NULL;
return TRUE;
break;
case 0xdc:
/* 'DC' + '0E' + AUTS(14) = 16 */
if (len < 16)
goto umts_end;
/*
* Response parameters/data, case 2, 3G security context,
* synchronisation failure:
*
* "Synchronisation failure" tag = 'DC'
* 'DC' + L1 + AUTS(L1)
*/
l = *ptr++; /* L1 */
if ((ptr + l) > end)
return FALSE;
/* sync error */
if (buffer[1] != 0x0e)
goto umts_end;
auts->data = ptr;
auts->len = l;
ptr += l;
*auts = buffer + 2;
if (ptr != end)
return FALSE;
break;
default:
goto umts_end;
}
return TRUE;
return TRUE;
case 0x04:
/*
* Response parameters/data, case 3, GSM security context,
* command successful:
*
* 4 + SRES(4) + 8 + Kc(8)
*/
l = 4; /* Already skipped this one */
if ((ptr + l) > end)
return FALSE;
sres->data = ptr;
sres->len = l;
ptr += l;
if (ptr == end)
return FALSE;
l = *ptr++; /* 8 */
if (l != 8 || (ptr + l) > end)
return FALSE;
kc->data = ptr;
kc->len = l;
ptr += l;
umts_end:
if (ptr != end)
return FALSE;
return TRUE;
default:
break;
}
return FALSE;
}
......
......@@ -314,9 +314,13 @@ struct sim_ef_info {
enum sim_file_access perm_update;
};
struct sim_app_record {
struct sim_aid {
unsigned char aid[16];
int aid_len;
unsigned int len;
};
struct sim_app_record {
struct sim_aid aid;
char *label;
enum sim_app_type type;
};
......@@ -371,6 +375,11 @@ struct comprehension_tlv_builder {
struct ber_tlv_builder *parent;
};
struct data_block {
const unsigned char *data;
unsigned int len;
};
void simple_tlv_iter_init(struct simple_tlv_iter *iter,
const unsigned char *pdu, unsigned int len);
gboolean simple_tlv_iter_next(struct simple_tlv_iter *iter);
......@@ -526,10 +535,10 @@ int sim_build_umts_authenticate(unsigned char *buffer, int len,
int sim_build_gsm_authenticate(unsigned char *buffer, int len,
const unsigned char *rand);
gboolean sim_parse_umts_authenticate(const unsigned char *buffer,
int len, const unsigned char **res, const unsigned char **ck,
const unsigned char **ik, const unsigned char **auts,
const unsigned char **kc);
gboolean sim_parse_umts_authenticate(const unsigned char *buffer, int len,
struct data_block *res, struct data_block *ck,
struct data_block *ik, struct data_block *auts,
struct data_block *sres, struct data_block *kc);
gboolean sim_parse_gsm_authenticate(const unsigned char *buffer, int len,
const unsigned char **sres, const unsigned char **kc);
......@@ -3,6 +3,7 @@
* oFono - Open Source Telephony
*
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
* Copyright (C) 2015-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -491,12 +492,12 @@ static void test_application_entry_decode(void)
app[0] = entries->next->data;
app[1] = entries->data;
g_assert(app[0]->aid_len == 0x10);
g_assert(!memcmp(app[0]->aid, &ef_dir[4], 0x10));
g_assert(app[0]->aid.len == 0x10);
g_assert(!memcmp(app[0]->aid.aid, &ef_dir[4], 0x10));
g_assert(app[0]->label == NULL);
g_assert(app[1]->aid_len == 0x0c);
g_assert(!memcmp(app[1]->aid, &ef_dir[37], 0x0c));
g_assert(app[1]->aid.len == 0x0c);
g_assert(!memcmp(app[1]->aid.aid, &ef_dir[37], 0x0c));
g_assert(app[1]->label != NULL);
g_assert(!strcmp(app[1]->label, "MIDPfiles"));
......@@ -529,32 +530,34 @@ static void test_get_2g_path(void)
static void test_auth_build_parse(void)
{
unsigned char auth_cmd[40];
const unsigned char rand[16] = { 0x00, 0x01, 0x02, 0x03, 0x04,0x05,
const unsigned char rand[] = { 0x00, 0x01, 0x02, 0x03, 0x04,0x05,
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
0x0e, 0x0f };
const unsigned char sres[4] = { 0x00, 0x11, 0x22, 0x33 };
const unsigned char sres[] = { 0x00, 0x11, 0x22, 0x33 };
const unsigned char *sres_p;
struct data_block sres_b;
const unsigned char kc[8] = { 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56,
0x78, 0x9a };
const unsigned char *kc_p;
struct data_block kc_b;
const unsigned char gsm_success[] = { 0x04, 0x00, 0x11, 0x22, 0x33,
0x08,0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x9a };
const unsigned char autn[16] = { 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a,
const unsigned char autn[] = { 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a,
0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02,
0x01, 0x00 };
const unsigned char res[8] = { 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa,
const unsigned char res[] = { 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa,
0x11, 0x22 };
const unsigned char *res_p;
const unsigned char ck[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
struct data_block res_b;
const unsigned char ck[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
const unsigned char *ck_p;