Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

774 lines
16 KiB

  1. /*++
  2. Copyright (c) 1997 SCM Microsystems, Inc.
  3. Module Name:
  4. StcCmd.c
  5. Abstract:
  6. Basic command functions for STC smartcard reader
  7. Environment:
  8. Revision History:
  9. PP 01.19.1999 1.01 Modification for PC/SC
  10. YL 1.00 Initial Version
  11. --*/
  12. #include "common.h"
  13. #include "StcCmd.h"
  14. #include "usbcom.h"
  15. #include "stcusbnt.h"
  16. const STC_REGISTER STCInitialize[] =
  17. {
  18. { ADR_SC_CONTROL, 0x01, 0x00 }, // reset
  19. { ADR_CLOCK_CONTROL, 0x01, 0x01 },
  20. { ADR_CLOCK_CONTROL, 0x01, 0x03 },
  21. { ADR_UART_CONTROL, 0x01, 0x27 },
  22. { ADR_UART_CONTROL, 0x01, 0x4F },
  23. { ADR_IO_CONFIG, 0x01, 0x02 }, // 0x10 eva board
  24. { ADR_FIFO_CONFIG, 0x01, 0x81 },
  25. { ADR_INT_CONTROL, 0x01, 0x11 },
  26. { 0x0E, 0x01, 0xC0 },
  27. { 0x00, 0x00, 0x00 },
  28. };
  29. const STC_REGISTER STCClose[] =
  30. {
  31. { ADR_INT_CONTROL, 0x01, 0x00 },
  32. { ADR_SC_CONTROL, 0x01, 0x00 }, // reset
  33. { ADR_UART_CONTROL, 0x01, 0x40 },
  34. { ADR_CLOCK_CONTROL, 0x01, 0x01 },
  35. { ADR_CLOCK_CONTROL, 0x01, 0x00 },
  36. { 0x00, 0x00, 0x00 },
  37. };
  38. NTSTATUS
  39. STCResetInterface(
  40. PREADER_EXTENSION ReaderExtension)
  41. /*++
  42. Description:
  43. Arguments:
  44. ReaderExtension context of call
  45. Return Value:
  46. --*/
  47. {
  48. NTSTATUS NtStatus = STATUS_SUCCESS;
  49. DWORD dwETU;
  50. dwETU = 0x7401 | 0x0080;
  51. NtStatus=IFWriteSTCRegister(
  52. ReaderExtension,
  53. ADR_ETULENGTH15,
  54. 2,
  55. (UCHAR *)&dwETU);
  56. return(NtStatus);
  57. }
  58. NTSTATUS
  59. STCReset(
  60. PREADER_EXTENSION ReaderExtension,
  61. UCHAR Device,
  62. BOOLEAN WarmReset,
  63. PUCHAR pATR,
  64. PULONG pATRLength)
  65. /*++
  66. Description:
  67. performs a reset of ICC
  68. Arguments:
  69. ReaderExtension context of call
  70. Device device requested
  71. WarmReset kind of ICC reset
  72. pATR ptr to ATR buffer, NULL if no ATR required
  73. pATRLength size of ATR buffer / length of ATR
  74. Return Value:
  75. STATUS_SUCCESS
  76. STATUS_NO_MEDIA
  77. STATUS_UNRECOGNIZED_MEDIA
  78. error values from IFRead / IFWrite
  79. --*/
  80. {
  81. NTSTATUS NTStatus = STATUS_SUCCESS;
  82. // set UART to autolearn mode
  83. NTStatus = STCInitUART( ReaderExtension, TRUE );
  84. if( NTStatus == STATUS_SUCCESS)
  85. {
  86. //
  87. // set default frequency for ATR
  88. //
  89. NTStatus = STCSetFDIV( ReaderExtension, FREQ_DIV );
  90. if( NTStatus == STATUS_SUCCESS && ( !WarmReset ))
  91. {
  92. //
  93. // deactivate contacts
  94. //
  95. NTStatus = STCPowerOff( ReaderExtension );
  96. }
  97. //
  98. // set power to card
  99. //
  100. if( NTStatus == STATUS_SUCCESS)
  101. {
  102. NTStatus = STCPowerOn( ReaderExtension );
  103. if( NTStatus == STATUS_SUCCESS)
  104. {
  105. NTStatus = STCReadATR( ReaderExtension, pATR, pATRLength );
  106. }
  107. }
  108. }
  109. if( NTStatus != STATUS_SUCCESS )
  110. {
  111. STCPowerOff( ReaderExtension );
  112. }
  113. return( NTStatus );
  114. }
  115. NTSTATUS
  116. STCReadATR(
  117. PREADER_EXTENSION ReaderExtension,
  118. PUCHAR pATR,
  119. PULONG pATRLen)
  120. /*++
  121. Description:
  122. Read and analize the ATR
  123. Arguments:
  124. ReaderExtension context of call
  125. pATR ptr to ATR buffer,
  126. pATRLen size of ATR buffer / length of ATR
  127. Return Value:
  128. --*/
  129. {
  130. NTSTATUS NTStatus = STATUS_SUCCESS;
  131. UCHAR T0_Yx,
  132. T0_K, // number of historical bytes
  133. Protocol;
  134. ULONG ATRLen;
  135. //
  136. // set read timeout for ATR
  137. //
  138. ReaderExtension->ReadTimeout = 250; // only 250ms for this firs ATR
  139. //
  140. // read TS if active low reset
  141. //
  142. NTStatus = IFReadSTCData( ReaderExtension, pATR, 1 );
  143. if( NTStatus == STATUS_IO_TIMEOUT )
  144. {
  145. ReaderExtension->ReadTimeout = 2500;
  146. NTStatus = STCSetRST( ReaderExtension, TRUE );
  147. if( NTStatus == STATUS_SUCCESS )
  148. {
  149. NTStatus = IFReadSTCData( ReaderExtension, pATR, 1 );
  150. }
  151. }
  152. Protocol = PROTOCOL_TO;
  153. ATRLen = 1;
  154. if( NTStatus == STATUS_SUCCESS )
  155. {
  156. // T0
  157. NTStatus = IFReadSTCData( ReaderExtension, pATR + ATRLen, 1 );
  158. ATRLen++;
  159. /* Convention management */
  160. if ( pATR[0] == 0x03 ) /* Direct convention */
  161. {
  162. pATR[0] = 0x3F;
  163. }
  164. if ( ( pATR[0] != 0x3F ) && ( pATR[0] != 0x3B ) )
  165. {
  166. NTStatus = STATUS_DATA_ERROR;
  167. }
  168. if( NTStatus == STATUS_SUCCESS )
  169. {
  170. ULONG Request;
  171. // number of historical bytes
  172. T0_K = (UCHAR) ( pATR[ATRLen-1] & 0x0F );
  173. // coding of TA, TB, TC, TD
  174. T0_Yx = (UCHAR) ( pATR[ATRLen-1] & 0xF0 ) >> 4;
  175. while(( NTStatus == STATUS_SUCCESS ) && T0_Yx )
  176. {
  177. UCHAR Mask;
  178. // evaluate presence of TA, TB, TC, TD
  179. Mask = T0_Yx;
  180. Request = 0;
  181. while( Mask )
  182. {
  183. if( Mask & 1 )
  184. {
  185. Request++;
  186. }
  187. Mask >>= 1;
  188. }
  189. NTStatus = IFReadSTCData( ReaderExtension, pATR + ATRLen, Request );
  190. ATRLen += Request;
  191. if (ATRLen >= ATR_SIZE) {
  192. NTStatus = STATUS_UNRECOGNIZED_MEDIA;
  193. break;
  194. }
  195. if( T0_Yx & TDx )
  196. {
  197. // high nibble of TD codes the next set of TA, TB, TC, TD
  198. T0_Yx = ( pATR[ATRLen-1] & 0xF0 ) >> 4;
  199. // low nibble of TD codes the protocol
  200. Protocol = pATR[ATRLen-1] & 0x0F;
  201. }
  202. else
  203. {
  204. break;
  205. }
  206. }
  207. if( NTStatus == STATUS_SUCCESS )
  208. {
  209. // historical bytes
  210. NTStatus = IFReadSTCData( ReaderExtension, pATR + ATRLen, T0_K );
  211. // check sum
  212. if( NTStatus == STATUS_SUCCESS )
  213. {
  214. ATRLen += T0_K;
  215. if( (ATRLen < ATR_SIZE) && (Protocol >= PROTOCOL_T1) )
  216. {
  217. NTStatus = IFReadSTCData( ReaderExtension, pATR + ATRLen, 1 );
  218. if( NTStatus == STATUS_SUCCESS )
  219. {
  220. ATRLen++;
  221. }
  222. else if( NTStatus == STATUS_IO_TIMEOUT )
  223. {
  224. // some cards don't support the TCK
  225. NTStatus = STATUS_SUCCESS;
  226. }
  227. } else {
  228. if (ATRLen >= ATR_SIZE) {
  229. NTStatus = STATUS_UNRECOGNIZED_MEDIA;
  230. }
  231. }
  232. }
  233. }
  234. }
  235. }
  236. if( NTStatus == STATUS_IO_TIMEOUT )
  237. {
  238. NTStatus = STATUS_UNRECOGNIZED_MEDIA;
  239. }
  240. if(( NTStatus == STATUS_SUCCESS ) && ( pATRLen != NULL ))
  241. {
  242. *pATRLen = ATRLen;
  243. }
  244. return( NTStatus );
  245. }
  246. NTSTATUS
  247. STCPowerOff(
  248. PREADER_EXTENSION ReaderExtension )
  249. /*++
  250. Description:
  251. Deactivates the requested device
  252. Arguments:
  253. ReaderExtension context of call
  254. Return Value:
  255. STATUS_SUCCESS
  256. error values from IFRead / IFWrite
  257. --*/
  258. {
  259. NTSTATUS NTStatus = STATUS_SUCCESS;
  260. UCHAR SCCtrl;
  261. // clear SIM
  262. SCCtrl=0x11;
  263. NTStatus=IFWriteSTCRegister(
  264. ReaderExtension,
  265. ADR_INT_CONTROL,
  266. 1,
  267. &SCCtrl);
  268. SCCtrl = 0x00;
  269. NTStatus = IFWriteSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1, &SCCtrl );
  270. return( NTStatus );
  271. }
  272. NTSTATUS
  273. STCPowerOn(
  274. PREADER_EXTENSION ReaderExtension )
  275. /*++
  276. Description:
  277. Deactivates the requested device
  278. Arguments:
  279. ReaderExtension context of call
  280. Return Value:
  281. STATUS_SUCCESS
  282. error values from IFRead / IFWrite
  283. --*/
  284. {
  285. NTSTATUS NTStatus = STATUS_SUCCESS;
  286. UCHAR SCCtrl,Byte;
  287. Byte = 0x02;
  288. NTStatus = IFWriteSTCRegister(
  289. ReaderExtension,
  290. ADR_IO_CONFIG,
  291. 1,
  292. &Byte
  293. );
  294. SCCtrl = 0x40; // vcc
  295. NTStatus = IFWriteSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1, &SCCtrl );
  296. if( NTStatus == STATUS_SUCCESS )
  297. {
  298. SCCtrl = 0x41; // vpp
  299. NTStatus = IFWriteSTCRegister(
  300. ReaderExtension,
  301. ADR_SC_CONTROL,
  302. 1,
  303. &SCCtrl
  304. );
  305. // set SIM
  306. SCCtrl = 0x13;
  307. NTStatus=IFWriteSTCRegister(
  308. ReaderExtension,
  309. ADR_INT_CONTROL,
  310. 1,
  311. &SCCtrl);
  312. if( NTStatus == STATUS_SUCCESS )
  313. {
  314. SCCtrl = 0xD1; // vcc, clk, io
  315. NTStatus = IFWriteSTCRegister(
  316. ReaderExtension,
  317. ADR_SC_CONTROL,
  318. 1,
  319. &SCCtrl
  320. );
  321. }
  322. }
  323. return( NTStatus );
  324. }
  325. NTSTATUS
  326. STCSetRST(
  327. PREADER_EXTENSION ReaderExtension,
  328. BOOLEAN On)
  329. /*++
  330. Description:
  331. Arguments:
  332. ReaderExtension context of call
  333. Return Value:
  334. STATUS_SUCCESS
  335. error values from IFRead / IFWrite
  336. --*/
  337. {
  338. NTSTATUS NTStatus = STATUS_SUCCESS;
  339. UCHAR SCCtrl = 0;
  340. NTStatus = IFReadSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1,&SCCtrl );
  341. if( NTStatus == STATUS_SUCCESS )
  342. {
  343. if( On )
  344. {
  345. SCCtrl |= 0x20;
  346. }
  347. else
  348. {
  349. SCCtrl &= ~0x20;
  350. }
  351. NTStatus = IFWriteSTCRegister(
  352. ReaderExtension,
  353. ADR_SC_CONTROL,
  354. 1,
  355. &SCCtrl
  356. );
  357. }
  358. return(NTStatus);
  359. }
  360. NTSTATUS
  361. STCConfigureSTC(
  362. PREADER_EXTENSION ReaderExtension,
  363. PSTC_REGISTER pConfiguration
  364. )
  365. {
  366. NTSTATUS NTStatus = STATUS_SUCCESS;
  367. UCHAR Value;
  368. do
  369. {
  370. if( pConfiguration->Register == ADR_INT_CONTROL )
  371. {
  372. // Read interrupt status register to acknoledge wrong states
  373. NTStatus = IFReadSTCRegister(
  374. ReaderExtension,
  375. ADR_INT_STATUS,
  376. 1,
  377. &Value
  378. );
  379. }
  380. Value = (UCHAR) pConfiguration->Value;
  381. NTStatus = IFWriteSTCRegister(
  382. ReaderExtension,
  383. pConfiguration->Register,
  384. pConfiguration->Size,
  385. (PUCHAR)&pConfiguration->Value
  386. );
  387. if (NTStatus == STATUS_NO_MEDIA)
  388. {
  389. // ignore that no card is in the reader
  390. NTStatus = STATUS_SUCCESS;
  391. }
  392. // delay to stabilize the oscilator clock:
  393. if( pConfiguration->Register == ADR_CLOCK_CONTROL )
  394. {
  395. SysDelay( 100 );
  396. }
  397. pConfiguration++;
  398. } while(NTStatus == STATUS_SUCCESS && pConfiguration->Size);
  399. return NTStatus;
  400. }
  401. NTSTATUS
  402. STCSetETU(
  403. PREADER_EXTENSION ReaderExtension,
  404. ULONG NewETU)
  405. /*++
  406. Description:
  407. Arguments:
  408. ReaderExtension context of call
  409. Return Value:
  410. STATUS_SUCCESS
  411. error values from IFRead / IFWrite
  412. --*/
  413. {
  414. NTSTATUS NTStatus = STATUS_DATA_ERROR;
  415. UCHAR ETU[2];
  416. SmartcardDebug(
  417. DEBUG_TRACE,
  418. ("%s!STCSetETU %d\n",
  419. DRIVER_NAME,
  420. NewETU));
  421. if( NewETU < 0x0FFF )
  422. {
  423. NTStatus = IFReadSTCRegister(
  424. ReaderExtension,
  425. ADR_ETULENGTH15,
  426. 2,
  427. ETU);
  428. if( NTStatus == STATUS_SUCCESS )
  429. {
  430. //
  431. // save all RFU bits
  432. //
  433. ETU[1] = (UCHAR) NewETU;
  434. ETU[0] = (UCHAR)(( ETU[0] & 0xF0 ) | ( NewETU >> 8 ));
  435. NTStatus = IFWriteSTCRegister(
  436. ReaderExtension,
  437. ADR_ETULENGTH15,
  438. 2,
  439. ETU);
  440. }
  441. }
  442. return(NTStatus);
  443. }
  444. NTSTATUS
  445. STCSetCGT(
  446. PREADER_EXTENSION ReaderExtension,
  447. ULONG NewCGT)
  448. /*++
  449. Description:
  450. Arguments:
  451. ReaderExtension context of call
  452. Return Value:
  453. STATUS_SUCCESS
  454. error values from IFRead / IFWrite
  455. --*/
  456. {
  457. NTSTATUS NTStatus = STATUS_DATA_ERROR;
  458. UCHAR CGT[2];
  459. SmartcardDebug(
  460. DEBUG_TRACE,
  461. ("%s!STCSetCGT %d\n",
  462. DRIVER_NAME,
  463. NewCGT));
  464. if( NewCGT < 0x01FF )
  465. {
  466. NTStatus = IFReadSTCRegister(
  467. ReaderExtension,
  468. ADR_CGT8,
  469. 2,
  470. CGT);
  471. if( NTStatus == STATUS_SUCCESS )
  472. {
  473. //
  474. // save all RFU bits
  475. //
  476. CGT[1] = ( UCHAR )NewCGT;
  477. CGT[0] = (UCHAR)(( CGT[0] & 0xFE ) | ( NewCGT >> 8 ));
  478. NTStatus = IFWriteSTCRegister(
  479. ReaderExtension,
  480. ADR_CGT8,
  481. 2,
  482. CGT);
  483. }
  484. }
  485. return(NTStatus);
  486. }
  487. NTSTATUS
  488. STCSetCWT(
  489. PREADER_EXTENSION ReaderExtension,
  490. ULONG NewCWT)
  491. /*++
  492. Description:
  493. Arguments:
  494. ReaderExtension context of call
  495. Return Value:
  496. STATUS_SUCCESS
  497. error values from IFRead / IFWrite
  498. --*/
  499. {
  500. NTSTATUS NTStatus = STATUS_SUCCESS;
  501. UCHAR CWT[4];
  502. SmartcardDebug(
  503. DEBUG_TRACE,
  504. ("%s!STCSetCWT %d\n",
  505. DRIVER_NAME,
  506. NewCWT));
  507. // little indians...
  508. CWT[0] = (( PUCHAR )&NewCWT )[3];
  509. CWT[1] = (( PUCHAR )&NewCWT )[2];
  510. CWT[2] = (( PUCHAR )&NewCWT )[1];
  511. CWT[3] = (( PUCHAR )&NewCWT )[0];
  512. NTStatus = IFWriteSTCRegister(
  513. ReaderExtension,
  514. ADR_CWT31,
  515. 4,
  516. CWT );
  517. return(NTStatus);
  518. }
  519. NTSTATUS
  520. STCSetBWT(
  521. PREADER_EXTENSION ReaderExtension,
  522. ULONG NewBWT)
  523. /*++
  524. Description:
  525. Arguments:
  526. ReaderExtension context of call
  527. Return Value:
  528. STATUS_SUCCESS
  529. error values from IFRead / IFWrite
  530. --*/
  531. {
  532. NTSTATUS NTStatus = STATUS_SUCCESS;
  533. UCHAR BWT[4];
  534. SmartcardDebug(
  535. DEBUG_TRACE,
  536. ("%s!STCSetBWT %d\n",
  537. DRIVER_NAME,
  538. NewBWT));
  539. // little indians...
  540. BWT[0] = (( PUCHAR )&NewBWT )[3];
  541. BWT[1] = (( PUCHAR )&NewBWT )[2];
  542. BWT[2] = (( PUCHAR )&NewBWT )[1];
  543. BWT[3] = (( PUCHAR )&NewBWT )[0];
  544. NTStatus = IFWriteSTCRegister(
  545. ReaderExtension,
  546. ADR_BWT31,
  547. 4,
  548. BWT );
  549. return(NTStatus);
  550. }
  551. NTSTATUS
  552. STCSetFDIV(
  553. PREADER_EXTENSION ReaderExtension,
  554. ULONG Factor)
  555. /*++
  556. Description:
  557. Arguments:
  558. ReaderExtension context of call
  559. Return Value:
  560. STATUS_SUCCESS
  561. error values from IFRead / IFWrite
  562. --*/
  563. {
  564. NTSTATUS NTStatus = STATUS_SUCCESS;
  565. UCHAR DIV = 0;
  566. NTStatus = IFReadSTCRegister(
  567. ReaderExtension,
  568. ADR_ETULENGTH15,
  569. 1,
  570. &DIV );
  571. if( NTStatus == STATUS_SUCCESS )
  572. {
  573. switch( Factor )
  574. {
  575. case 1:
  576. DIV &= ~M_DIV0;
  577. DIV &= ~M_DIV1;
  578. break;
  579. case 2:
  580. DIV |= M_DIV0;
  581. DIV &= ~M_DIV1;
  582. break;
  583. case 4 :
  584. DIV &= ~M_DIV0;
  585. DIV |= M_DIV1;
  586. break;
  587. case 8 :
  588. DIV |= M_DIV0;
  589. DIV |= M_DIV1;
  590. break;
  591. default :
  592. NTStatus = STATUS_DATA_ERROR;
  593. }
  594. if( NTStatus == STATUS_SUCCESS )
  595. {
  596. NTStatus = IFWriteSTCRegister(
  597. ReaderExtension,
  598. ADR_ETULENGTH15,
  599. 1,
  600. &DIV );
  601. }
  602. }
  603. return(NTStatus);
  604. }
  605. NTSTATUS
  606. STCInitUART(
  607. PREADER_EXTENSION ReaderExtension,
  608. BOOLEAN AutoLearn)
  609. /*++
  610. Description:
  611. Arguments:
  612. ReaderExtension context of call
  613. Return Value:
  614. STATUS_SUCCESS
  615. error values from IFRead / IFWrite
  616. --*/
  617. {
  618. NTSTATUS NTStatus = STATUS_SUCCESS;
  619. UCHAR Value;
  620. Value = AutoLearn ? 0x6F : 0x66;
  621. NTStatus = IFWriteSTCRegister(
  622. ReaderExtension,
  623. ADR_UART_CONTROL,
  624. 1,
  625. &Value );
  626. return( NTStatus );
  627. }
  628. //---------------------------------------- END OF FILE ----------------------------------------