btok_test.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. /*
  2. *******************************************************************************
  3. \file btok_test.c
  4. \brief Tests for STB 34.101.79 (btok)
  5. \project bee2/test
  6. \created 2022.07.07
  7. \version 2023.12.19
  8. \copyright The Bee2 authors
  9. \license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
  10. *******************************************************************************
  11. */
  12. #include <bee2/core/err.h>
  13. #include <bee2/core/hex.h>
  14. #include <bee2/core/mem.h>
  15. #include <bee2/core/prng.h>
  16. #include <bee2/core/str.h>
  17. #include <bee2/core/util.h>
  18. #include <bee2/crypto/belt.h>
  19. #include <bee2/crypto/bign.h>
  20. #include <bee2/crypto/bign96.h>
  21. #include <bee2/crypto/btok.h>
  22. /*
  23. *******************************************************************************
  24. Парольный автомат
  25. *******************************************************************************
  26. */
  27. static bool_t btokPwdTest()
  28. {
  29. btok_pwd_state state;
  30. // начальное состояние
  31. state.pin = pin3;
  32. state.auth = auth_none;
  33. // верный PIN
  34. if (!btokPwdTransition(&state, pin_ok) ||
  35. state.pin != pin3 || state.auth != auth_pin)
  36. return FALSE;
  37. // деактивировать PIN
  38. if (!btokPwdTransition(&state, pin_deactivate) ||
  39. state.pin != pind || state.auth != auth_none)
  40. return FALSE;
  41. // активировать PIN
  42. if (btokPwdTransition(&state, pin_ok) ||
  43. !btokPwdTransition(&state, puk_ok) ||
  44. !btokPwdTransition(&state, pin_activate) ||
  45. state.pin != pin3 || state.auth != auth_puk)
  46. return FALSE;
  47. // активировать CAN
  48. if (!btokPwdTransition(&state, can_bad) ||
  49. !btokPwdTransition(&state, can_ok) ||
  50. state.pin != pin3 || state.auth != auth_can)
  51. return FALSE;
  52. // неверный PIN
  53. if (!btokPwdTransition(&state, pin_bad) ||
  54. state.pin != pin2 || state.auth != auth_can ||
  55. !btokPwdTransition(&state, pin_bad) ||
  56. state.pin != pins || state.auth != auth_can ||
  57. btokPwdTransition(&state, pin_bad) ||
  58. !btokPwdTransition(&state, can_ok) ||
  59. state.pin != pin1 || state.auth != auth_can ||
  60. !btokPwdTransition(&state, pin_bad) ||
  61. state.pin != pin0 || state.auth != auth_can)
  62. return FALSE;
  63. // неверный PUK
  64. if (!btokPwdTransition(&state, auth_close) ||
  65. !btokPwdTransition(&state, puk_bad) ||
  66. state.pin != puk9 || state.auth != auth_none ||
  67. !btokPwdTransition(&state, puk_bad) ||
  68. state.pin != puk8 || state.auth != auth_none ||
  69. !btokPwdTransition(&state, puk_bad) ||
  70. state.pin != puk7 || state.auth != auth_none ||
  71. !btokPwdTransition(&state, puk_bad) ||
  72. state.pin != puk6 || state.auth != auth_none ||
  73. !btokPwdTransition(&state, puk_bad) ||
  74. state.pin != puk5 || state.auth != auth_none ||
  75. !btokPwdTransition(&state, puk_bad) ||
  76. state.pin != puk4 || state.auth != auth_none ||
  77. !btokPwdTransition(&state, puk_bad) ||
  78. state.pin != puk3 || state.auth != auth_none ||
  79. !btokPwdTransition(&state, puk_bad) ||
  80. state.pin != puk2 || state.auth != auth_none ||
  81. !btokPwdTransition(&state, puk_bad) ||
  82. state.pin != puk1 || state.auth != auth_none ||
  83. !btokPwdTransition(&state, puk_bad) ||
  84. state.pin != puk0 || state.auth != auth_none)
  85. return FALSE;
  86. // верные PUK и CAN при полной блокировке PIN
  87. if (btokPwdTransition(&state, pin_ok) ||
  88. !btokPwdTransition(&state, puk_ok) ||
  89. state.pin != puk0 || state.auth != auth_puk ||
  90. !btokPwdTransition(&state, can_ok) ||
  91. state.pin != puk0 || state.auth != auth_can)
  92. return FALSE;
  93. // все нормально
  94. return TRUE;
  95. }
  96. /*
  97. *******************************************************************************
  98. CV-сертификаты
  99. *******************************************************************************
  100. */
  101. static bool_t btokCVCTest()
  102. {
  103. octet echo[256];
  104. btok_cvc_t cvc0[1];
  105. btok_cvc_t cvc1[1];
  106. btok_cvc_t cvc2[1];
  107. btok_cvc_t cvc3[1];
  108. bign_params params[1];
  109. octet privkey0[64];
  110. octet privkey1[48];
  111. octet privkey2[32];
  112. octet privkey3[24];
  113. octet cert0[400];
  114. size_t cert0_len, cert0_len1;
  115. octet cert1[400];
  116. size_t cert1_len, cert1_len1;
  117. octet cert2[400];
  118. size_t cert2_len, cert2_len1;
  119. octet cert3[400];
  120. size_t cert3_len, cert3_len1;
  121. // запустить ГПСЧ
  122. prngEchoStart(echo, beltH(), 256);
  123. // определить максимальную длину сертификата
  124. memSetZero(cvc0, sizeof(btok_cvc_t));
  125. strCopy(cvc0->authority, "BYCA00000000");
  126. strCopy(cvc0->holder, "BYCA00000000");
  127. hexTo(cvc0->from, "020200070007");
  128. hexTo(cvc0->until, "090900070007");
  129. memSet(cvc0->hat_eid, 0xEE, sizeof(cvc0->hat_eid));
  130. memSet(cvc0->hat_esign, 0x77, sizeof(cvc0->hat_esign));
  131. cvc0->pubkey_len = 128;
  132. if (btokCVCCheck(cvc0) == ERR_OK)
  133. return FALSE;
  134. if (bignParamsStd(params, "1.2.112.0.2.0.34.101.45.3.3") != ERR_OK ||
  135. bignKeypairGen(privkey0, cvc0->pubkey, params, prngEchoStepR,
  136. echo) != ERR_OK ||
  137. btokCVCCheck(cvc0) != ERR_OK)
  138. return FALSE;
  139. if (btokCVCWrap(0, 0, cvc0, privkey0, 64) != ERR_OK)
  140. return FALSE;
  141. cvc0->pubkey_len = 0;
  142. if (btokCVCWrap(0, &cert0_len, cvc0, privkey0, 64) != ERR_OK ||
  143. cert0_len != 365 || cert0_len > sizeof(cert0))
  144. return FALSE;
  145. // выпустить cert0
  146. memSetZero(cvc0->authority, sizeof(cvc0->authority));
  147. strCopy(cvc0->authority, "BYCA0000");
  148. memSetZero(cvc0->holder, sizeof(cvc0->holder));
  149. strCopy(cvc0->holder, "BYCA0000");
  150. if (btokCVCWrap(0, &cert0_len, cvc0, privkey0, 64) != ERR_OK ||
  151. cert0_len > 365 || cert0_len > sizeof(cert0) ||
  152. btokCVCWrap(cert0, &cert0_len1, cvc0, privkey0, 64) != ERR_OK ||
  153. cert0_len1 != cert0_len)
  154. return FALSE;
  155. // разобрать cert0
  156. if (btokCVCUnwrap(cvc1, cert0, cert0_len, 0, 0) != ERR_OK ||
  157. btokCVCUnwrap(cvc1, cert0, cert0_len, cvc0->pubkey,
  158. cvc0->pubkey_len) != ERR_OK ||
  159. !memEq(cvc0, cvc1, sizeof(btok_cvc_t)) ||
  160. btokCVCLen(cert0, cert0_len) != cert0_len ||
  161. btokCVCLen(cert0, cert0_len + 1) != cert0_len ||
  162. btokCVCLen(cert0, cert0_len - 1) != SIZE_MAX ||
  163. btokCVCMatch(cert0, cert0_len, privkey0, 64) != ERR_OK)
  164. return FALSE;
  165. // составить и проверить cvc1
  166. memSetZero(cvc1, sizeof(btok_cvc_t));
  167. strCopy(cvc1->authority, "BYCA0000");
  168. strCopy(cvc1->holder, "BYCA1000");
  169. hexTo(cvc1->from, "020200070102");
  170. hexTo(cvc1->until, "020201010300");
  171. memSet(cvc1->hat_eid, 0xDD, sizeof(cvc1->hat_eid));
  172. memSet(cvc1->hat_esign, 0x33, sizeof(cvc1->hat_esign));
  173. cvc1->pubkey_len = 96;
  174. if (bignParamsStd(params, "1.2.112.0.2.0.34.101.45.3.2") != ERR_OK ||
  175. bignKeypairGen(privkey1, cvc1->pubkey, params, prngEchoStepR,
  176. echo) != ERR_OK ||
  177. btokCVCCheck(cvc1) != ERR_OK)
  178. return FALSE;
  179. // создать pre-cert1 (запрос на выпуск сертификата)
  180. if (btokCVCWrap(0, &cert1_len, cvc1, privkey1, 48) != ERR_OK ||
  181. cert1_len > sizeof(cert1) ||
  182. btokCVCWrap(cert1, 0, cvc1, privkey1, 48) != ERR_OK ||
  183. btokCVCWrap(cert1, &cert1_len1, cvc1, privkey1, 48) != ERR_OK ||
  184. cert1_len1 != cert1_len)
  185. return FALSE;
  186. // разобрать pre-cert1:
  187. // - извлечь открытый ключ,
  188. // - проверить подпись,
  189. // - проверить соответствие authority <=> holder
  190. if (btokCVCUnwrap(cvc1, cert1, cert1_len, 0, 0) != ERR_OK ||
  191. btokCVCUnwrap(cvc2, cert1, cert1_len, cvc1->pubkey,
  192. cvc1->pubkey_len) != ERR_OK ||
  193. !memEq(cvc1, cvc2, sizeof(btok_cvc_t)) ||
  194. !strEq(cvc1->authority, cvc0->holder))
  195. return FALSE;
  196. // создать cert1
  197. if (btokCVCWrap(0, &cert1_len, cvc1, privkey0, 64) != ERR_OK ||
  198. cert1_len > sizeof(cert1) ||
  199. btokCVCWrap(cert1, &cert1_len1, cvc1, privkey0, 64) != ERR_OK ||
  200. cert1_len1 != cert1_len)
  201. return FALSE;
  202. // составить cvc2
  203. memSetZero(cvc2, sizeof(btok_cvc_t));
  204. strCopy(cvc2->authority, "BYCA1000");
  205. strCopy(cvc2->holder, "590082394654");
  206. hexTo(cvc2->from, "020200070102");
  207. hexTo(cvc2->until, "030901020301");
  208. memSet(cvc2->hat_eid, 0x88, sizeof(cvc2->hat_eid));
  209. memSet(cvc2->hat_esign, 0x11, sizeof(cvc2->hat_esign));
  210. cvc2->pubkey_len = 64;
  211. if (bignParamsStd(params, "1.2.112.0.2.0.34.101.45.3.1") != ERR_OK ||
  212. bignKeypairGen(privkey2, cvc2->pubkey, params, prngEchoStepR,
  213. echo) != ERR_OK ||
  214. btokCVCCheck(cvc2) != ERR_OK)
  215. return FALSE;
  216. // выпустить cert2
  217. if (btokCVCIss(cert2, &cert2_len, cvc2, cert1, cert1_len - 1,
  218. privkey1, 48) == ERR_OK ||
  219. btokCVCIss(cert2, &cert2_len, cvc2, cert1, cert1_len,
  220. privkey1, 48 + 1) == ERR_OK ||
  221. btokCVCIss(0, &cert2_len, cvc2, cert1, cert1_len,
  222. privkey1, 48) != ERR_OK ||
  223. cert2_len > sizeof(cert2) ||
  224. btokCVCIss(cert2, &cert2_len1, cvc2, cert1, cert1_len,
  225. privkey1, 48) != ERR_OK ||
  226. cert2_len1 != cert2_len)
  227. return FALSE;
  228. // составить cvc3
  229. memSetZero(cvc3, sizeof(btok_cvc_t));
  230. strCopy(cvc3->authority, "BYCA1000");
  231. strCopy(cvc3->holder, "590082394655");
  232. hexTo(cvc3->from, "020200070102");
  233. hexTo(cvc3->until, "020901020301");
  234. cvc3->pubkey_len = 48;
  235. if (bign96ParamsStd(params, "1.2.112.0.2.0.34.101.45.3.0") != ERR_OK ||
  236. bign96KeypairGen(privkey3, cvc3->pubkey, params, prngEchoStepR,
  237. echo) != ERR_OK ||
  238. btokCVCCheck(cvc3) != ERR_OK)
  239. return FALSE;
  240. // выпустить cert3
  241. if (btokCVCIss(0, &cert3_len, cvc3, cert1, cert1_len,
  242. privkey1, 48) != ERR_OK ||
  243. cert3_len > sizeof(cert3) ||
  244. btokCVCIss(cert3, &cert3_len1, cvc3, cert1, cert1_len,
  245. privkey1, 48) != ERR_OK ||
  246. cert3_len1 != cert3_len)
  247. return FALSE;
  248. // проверить сертификаты
  249. if (btokCVCVal(cert1, cert1_len, cert0, cert0_len, 0) != ERR_OK ||
  250. btokCVCVal(cert2, cert2_len, cert1, cert1_len, 0) != ERR_OK ||
  251. btokCVCVal(cert2, cert2_len, cert1, cert1_len, cvc0->from) == ERR_OK ||
  252. btokCVCVal(cert3, cert3_len, cert1, cert1_len, 0) != ERR_OK ||
  253. btokCVCVal2(cvc1, cert1, cert1_len, cvc0, 0) != ERR_OK ||
  254. btokCVCVal2(cvc2, cert2, cert2_len, cvc1, 0) != ERR_OK ||
  255. btokCVCVal2(cvc2, cert2, cert2_len, cvc1, cvc0->until) == ERR_OK ||
  256. btokCVCVal2(cvc3, cert3, cert3_len, cvc1, 0) != ERR_OK)
  257. return FALSE;
  258. // все хорошо
  259. return TRUE;
  260. }
  261. /*
  262. *******************************************************************************
  263. SM
  264. *******************************************************************************
  265. */
  266. static bool_t btokSMTest()
  267. {
  268. octet state_t[512];
  269. octet state_ct[512];
  270. octet stack[4096];
  271. apdu_cmd_t* cmd = (apdu_cmd_t*)stack;
  272. apdu_cmd_t* cmd1 = (apdu_cmd_t*)(stack + 1024);
  273. apdu_resp_t* resp = (apdu_resp_t*)(stack + 2 * 1024);
  274. apdu_resp_t* resp1 = (apdu_resp_t*)(stack + 3 * 1024);
  275. octet apdu[1024];
  276. size_t count, count1;
  277. size_t size, size1;
  278. // подготовить состояния
  279. if (sizeof(state_t) < btokSM_keep() ||
  280. sizeof(state_ct) < btokSM_keep())
  281. return FALSE;
  282. // запустить SM
  283. btokSMStart(state_t, beltH());
  284. btokSMStart(state_ct, beltH());
  285. // обработка команды без защиты
  286. memSetZero(cmd, sizeof(apdu_cmd_t));
  287. cmd->cla = 0x00, cmd->ins = 0xA4, cmd->p1 = 0x04, cmd->p2 = 0x04;
  288. cmd->cdf_len = 4, cmd->rdf_len = 256;
  289. hexTo(cmd->cdf, "54657374");
  290. if (btokSMCmdWrap(0, 0, cmd, 0) != ERR_OK ||
  291. btokSMCmdWrap(0, &count, cmd, 0) != ERR_OK ||
  292. count != 10 ||
  293. btokSMCmdWrap(apdu, 0, cmd, 0) != ERR_OK ||
  294. btokSMCmdWrap(apdu, &count, cmd, 0) != ERR_OK ||
  295. count != 10 ||
  296. !hexEq(apdu, "00A40404045465737400") ||
  297. btokSMCmdUnwrap(0, 0, apdu, count, 0) != ERR_OK ||
  298. btokSMCmdUnwrap(0, &size, apdu, count, 0) != ERR_OK ||
  299. size != sizeof(apdu_cmd_t) + 4 ||
  300. btokSMCmdUnwrap(cmd1, 0, apdu, count, 0) != ERR_OK ||
  301. btokSMCmdUnwrap(cmd1, &size, apdu, count, 0) != ERR_OK ||
  302. size != sizeof(apdu_cmd_t) + 4 ||
  303. !memEq(cmd, cmd1, size))
  304. return FALSE;
  305. // обработка ответа без защиты
  306. memSetZero(resp, sizeof(apdu_resp_t));
  307. resp->sw1 = 0x90, resp->sw2 = 0x00;
  308. resp->rdf_len = 20;
  309. hexTo(resp->rdf, "E012C00401FF8010C00402FF8010C00403FF8010");
  310. if (btokSMRespWrap(0, 0, resp, 0) != ERR_OK ||
  311. btokSMRespWrap(0, &count, resp, 0) != ERR_OK ||
  312. count != 22 ||
  313. btokSMRespWrap(apdu, 0, resp, 0) != ERR_OK ||
  314. btokSMRespWrap(apdu, &count, resp, 0) != ERR_OK ||
  315. count != 22 ||
  316. !hexEq(apdu,
  317. "E012C00401FF8010C00402FF8010C00403FF80109000") ||
  318. btokSMRespUnwrap(0, 0, apdu, count, 0) != ERR_OK ||
  319. btokSMRespUnwrap(0, &size, apdu, count, 0) != ERR_OK ||
  320. size != sizeof(apdu_resp_t) + 20 ||
  321. btokSMRespUnwrap(resp1, 0, apdu, count, 0) != ERR_OK ||
  322. btokSMRespUnwrap(resp1, &size, apdu, count, 0) != ERR_OK ||
  323. size != sizeof(apdu_resp_t) + 20 ||
  324. !memEq(resp, resp1, size))
  325. return FALSE;
  326. // обработка команды с защитой
  327. btokSMCtrInc(state_t), btokSMCtrInc(state_ct);
  328. if (btokSMCmdWrap(0, &count, cmd, state_t) != ERR_OK ||
  329. count != 26 ||
  330. btokSMCmdWrap(apdu, &count, cmd, state_t) != ERR_OK ||
  331. count != 26 ||
  332. !hexEq(apdu,
  333. "04A4040414"
  334. "8705020C4C0BFB"
  335. "970100"
  336. "8E08FBD50AD6814F90A9"
  337. "00") ||
  338. btokSMCmdUnwrap(0, &size, apdu, count, state_ct) != ERR_OK ||
  339. size != sizeof(apdu_cmd_t) + 4 ||
  340. btokSMCmdUnwrap(cmd1, &size, apdu, count, state_ct) != ERR_OK ||
  341. size != sizeof(apdu_cmd_t) + 4 ||
  342. !memEq(cmd, cmd1, size))
  343. return FALSE;
  344. // обработка ответа с защитой
  345. btokSMCtrInc(state_ct), btokSMCtrInc(state_t);
  346. if (btokSMRespWrap(0, &count, resp, state_ct) != ERR_OK ||
  347. count != 35 ||
  348. btokSMRespWrap(apdu, &count, resp, state_ct) != ERR_OK ||
  349. count != 35 ||
  350. !hexEq(apdu,
  351. "8715022A9042A60A85E50FAB446AC80B75F144B67EBD6D"
  352. "8E082C4DE31DFAA17635"
  353. "9000") ||
  354. btokSMRespUnwrap(0, &size, apdu, count, state_t) != ERR_OK ||
  355. size != sizeof(apdu_resp_t) + 20 ||
  356. btokSMRespUnwrap(resp1, &size, apdu, count, state_t) != ERR_OK ||
  357. size != sizeof(apdu_resp_t) + 20 ||
  358. !memEq(resp, resp1, size))
  359. return FALSE;
  360. // защита команд и ответов: сочетания длин
  361. cmd->cla = 0x00, cmd->ins = 0xA4, cmd->p1 = 0x04, cmd->p2 = 0x04;
  362. memSet(cmd->cdf, 0x36, 257);
  363. memSet(resp->rdf, 0x5C, 257);
  364. for (cmd->cdf_len = 0; cmd->cdf_len <= 257; ++cmd->cdf_len)
  365. for (cmd->rdf_len = 0; cmd->rdf_len <= 257; ++cmd->rdf_len)
  366. {
  367. btokSMCtrInc(state_t);
  368. if (btokSMCmdWrap(apdu, &count, cmd, state_t) != ERR_OK ||
  369. count > sizeof(apdu) ||
  370. btokSMCmdWrap(apdu, &count1, cmd, state_t) != ERR_OK ||
  371. count1 != count)
  372. return FALSE;
  373. btokSMCtrInc(state_ct);
  374. if (btokSMCmdUnwrap(0, &size, apdu, count, state_ct) != ERR_OK ||
  375. size > sizeof(stack) / 4 ||
  376. btokSMCmdUnwrap(cmd1, &size1, apdu, count, state_ct)
  377. != ERR_OK ||
  378. size1 != size || !memEq(cmd, cmd1, size))
  379. return FALSE;
  380. resp->rdf_len = cmd->rdf_len;
  381. btokSMCtrInc(state_ct);
  382. if (btokSMRespWrap(0, &count, resp, state_ct) != ERR_OK ||
  383. count > sizeof(apdu) ||
  384. btokSMRespWrap(apdu, &count1, resp, state_ct) != ERR_OK ||
  385. count1 != count)
  386. return FALSE;
  387. btokSMCtrInc(state_t);
  388. if (btokSMRespUnwrap(0, &size, apdu, count, state_t) != ERR_OK ||
  389. size > sizeof(stack) / 4 ||
  390. btokSMRespUnwrap(resp1, &size1, apdu, count, state_t)
  391. != ERR_OK ||
  392. size1 != size || !memEq(resp, resp1, size))
  393. return FALSE;
  394. }
  395. // все хорошо
  396. return TRUE;
  397. }
  398. /*
  399. *******************************************************************************
  400. BAUTH
  401. A = T, B = CT
  402. *******************************************************************************
  403. */
  404. static const char _da[] =
  405. "1F66B5B84B7339674533F0329C74F218"
  406. "34281FED0732429E0C79235FC273E269";
  407. static const char _db[] =
  408. "4C0E74B2CD5811AD21F23DE7E0FA742C"
  409. "3ED6EC483C461CE15C33A77AA308B7D2";
  410. static const char _certa[] =
  411. "5430303030303031"
  412. "BD1A5650179D79E03FCEE49D4C2BD5DD"
  413. "F54CE46D0CF11E4FF87BF7A890857FD0"
  414. "7AC6A60361E8C8173491686D461B2826"
  415. "190C2EDA5909054A9AB84D2AB9D99A90";
  416. static const char _certb[] =
  417. "4354303030303031"
  418. "CCEEF1A313A406649D15DA0A851D486A"
  419. "695B641B20611776252FFDCE39C71060"
  420. "7C9EA1F33C23D20DFCB8485A88BE6523"
  421. "A28ECC3215B47FA289D6C9BE1CE837C0";
  422. static err_t bakeTestCertVal(octet* pubkey, const bign_params* params,
  423. const octet* data, size_t len)
  424. {
  425. if (!memIsValid(params, sizeof(bign_params)) ||
  426. (params->l != 128 && params->l != 192 && params->l != 256) ||
  427. !memIsNullOrValid(pubkey, params->l / 2))
  428. return ERR_BAD_INPUT;
  429. if (!memIsValid(data, len) ||
  430. len < params->l / 2)
  431. return ERR_BAD_CERT;
  432. if (pubkey)
  433. memCopy(pubkey, data + (len - params->l / 2), params->l / 2);
  434. return ERR_OK;
  435. }
  436. static bool_t btokBAUTHTest()
  437. {
  438. bign_params params[1];
  439. octet echoa[64];
  440. octet echob[64];
  441. bake_settings settingsa[1];
  442. bake_settings settingsb[1];
  443. octet da[32];
  444. octet db[32];
  445. octet certdataa[8 /* Т0000001 */ + 64];
  446. octet certdatab[8 /* СТ000001 */ + 64];
  447. bake_cert certa[1];
  448. bake_cert certb[1];
  449. octet keya[32];
  450. octet keyb[32];
  451. octet statea[20000];
  452. octet stateb[20000];
  453. octet buf[1000];
  454. // загрузить долговременные параметры
  455. if (bignParamsStd(params, "1.2.112.0.2.0.34.101.45.3.1") != ERR_OK)
  456. return FALSE;
  457. // подготовить память
  458. if (sizeof(echoa) < prngEcho_keep() ||
  459. sizeof(statea) < btokBAuthT_keep(128) ||
  460. sizeof(stateb) < btokBAuthCT_keep(128))
  461. return FALSE;
  462. // загрузить личные ключи
  463. hexTo(da, _da);
  464. hexTo(db, _db);
  465. // загрузить сертификаты
  466. hexTo(certdataa, _certa);
  467. hexTo(certdatab, _certb);
  468. certa->data = certdataa;
  469. certa->len = strLen(_certa) / 2;
  470. certb->data = certdatab;
  471. certb->len = strLen(_certb) / 2;
  472. certa->val = certb->val = bakeTestCertVal;
  473. // очистка
  474. memSetZero(statea, sizeof(statea));
  475. memSetZero(stateb, sizeof(stateb));
  476. memSetZero(keya, sizeof(keya));
  477. memSetZero(keyb, sizeof(keyb));
  478. memSetZero(buf, sizeof(buf));
  479. // задать настройки, с аутентификацией КТ
  480. memSetZero(settingsa, sizeof(bake_settings));
  481. memSetZero(settingsb, sizeof(bake_settings));
  482. settingsa->kca = settingsb->kca = TRUE;
  483. settingsa->kcb = settingsb->kcb = TRUE;
  484. settingsa->rng = settingsb->rng = prngEchoStepR;
  485. settingsa->rng_state = echoa;
  486. settingsb->rng_state = echob;
  487. prngEchoStart(echoa, beltH(), 128);
  488. prngEchoStart(echob, beltH() + 128, 128);
  489. // инициализация
  490. if (btokBAuthTStart(statea, params, settingsa, da, certa) != ERR_OK ||
  491. btokBAuthCTStart(stateb, params, settingsb, db, certb) != ERR_OK)
  492. return FALSE;
  493. // шаги протокола, с аутентификацией КТ
  494. if (btokBAuthCTStep2(buf, certa, stateb) != ERR_OK ||
  495. btokBAuthTStep3(buf, buf, statea) != ERR_OK ||
  496. btokBAuthCTStep4(buf, buf, stateb) != ERR_OK ||
  497. btokBAuthTStep5(buf, 8 + 32 + certb->len,
  498. bakeTestCertVal, statea) != ERR_OK)
  499. return FALSE;
  500. // извлечение ключей
  501. if (btokBAuthCTStepG(keyb, stateb) != ERR_OK ||
  502. btokBAuthTStepG(keya, statea) != ERR_OK ||
  503. !memEq(keya, keyb, 32))
  504. return FALSE;
  505. // очистка
  506. memSetZero(statea, sizeof(statea));
  507. memSetZero(stateb, sizeof(stateb));
  508. memSetZero(keya, sizeof(keya));
  509. memSetZero(keyb, sizeof(keyb));
  510. memSetZero(buf, sizeof(buf));
  511. // задать настройки, без аутентификациии КТ
  512. memSetZero(settingsa, sizeof(bake_settings));
  513. memSetZero(settingsb, sizeof(bake_settings));
  514. settingsa->kca = settingsb->kca = TRUE;
  515. settingsa->kcb = settingsb->kcb = FALSE;
  516. settingsa->rng = settingsb->rng = prngEchoStepR;
  517. settingsa->rng_state = echoa;
  518. settingsb->rng_state = echob;
  519. prngEchoStart(echoa, beltH(), 128);
  520. prngEchoStart(echob, beltH() + 128, 128);
  521. // инициализация
  522. if (btokBAuthTStart(statea, params, settingsa, da, certa) != ERR_OK ||
  523. btokBAuthCTStart(stateb, params, settingsb, db, certb) != ERR_OK)
  524. return FALSE;
  525. // шаги протокола, без аутентификациии КТ
  526. if (btokBAuthCTStep2(buf, certa, stateb) != ERR_OK ||
  527. btokBAuthTStep3(buf, buf, statea) != ERR_OK ||
  528. btokBAuthCTStep4(buf, buf, stateb) != ERR_OK)
  529. return FALSE;
  530. // извлечение ключей
  531. if (btokBAuthCTStepG(keyb, stateb) != ERR_OK ||
  532. btokBAuthTStepG(keya, statea) != ERR_OK ||
  533. !memEq(keya, keyb, 32))
  534. return FALSE;
  535. // все нормально
  536. return TRUE;
  537. }
  538. /*
  539. *******************************************************************************
  540. Общий тест
  541. *******************************************************************************
  542. */
  543. bool_t btokTest()
  544. {
  545. return btokPwdTest() && btokCVCTest() && btokSMTest() && btokBAUTHTest();
  546. }