summaryrefslogtreecommitdiff
path: root/usr/src/common/ccid/atr.h
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/common/ccid/atr.h')
-rw-r--r--usr/src/common/ccid/atr.h198
1 files changed, 198 insertions, 0 deletions
diff --git a/usr/src/common/ccid/atr.h b/usr/src/common/ccid/atr.h
new file mode 100644
index 0000000000..50c01a44cb
--- /dev/null
+++ b/usr/src/common/ccid/atr.h
@@ -0,0 +1,198 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2019, Joyent, Inc.
+ */
+
+#ifndef _ATR_H
+#define _ATR_H
+
+/*
+ * Parse Answer-To-Reset values. This header file is private to illumos and
+ * should not be shipped or used by applications.
+ *
+ * This is based on ISO/IEC 7816-3:2006. It has been designed such that if newer
+ * revisions come out that define reserved values, they will be ignored until
+ * this code is updated.
+ */
+
+#include <sys/types.h>
+#include <sys/usb/clients/ccid/ccid.h>
+#ifndef _KERNEL
+#include <stdio.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The ATR must have at least 2 bytes and then may have up to 33 bytes.
+ */
+#define ATR_LEN_MIN 2
+#define ATR_LEN_MAX 33
+
+typedef enum atr_parsecode {
+ ATR_CODE_OK = 0,
+ ATR_CODE_TOO_SHORT,
+ ATR_CODE_TOO_LONG,
+ ATR_CODE_INVALID_TS,
+ ATR_CODE_OVERRUN,
+ ATR_CODE_UNDERRUN,
+ ATR_CODE_CHECKSUM_ERROR,
+ ATR_CODE_INVALID_TD1
+} atr_parsecode_t;
+
+typedef enum atr_protocol {
+ ATR_P_NONE = 0,
+ ATR_P_T0 = 1 << 0,
+ ATR_P_T1 = 1 << 1
+} atr_protocol_t;
+
+typedef enum atr_convention {
+ ATR_CONVENTION_DIRECT = 0x00,
+ ATR_CONVENTION_INVERSE = 0x01
+} atr_convention_t;
+
+typedef enum atr_clock_stop {
+ ATR_CLOCK_STOP_NONE = 0x00,
+ ATR_CLOCK_STOP_LOW = 0x01,
+ ATR_CLOCK_STOP_HI = 0x02,
+ ATR_CLOCK_STOP_BOTH = 0x03
+} atr_clock_stop_t;
+
+typedef enum atr_data_rate_choice {
+ /*
+ * Indicates that the reader cannot support the data rate needed for the
+ * ICC.
+ */
+ ATR_RATE_UNSUPPORTED = 0x00,
+ /*
+ * Indicates that the reader supports the ICC present, but must run at
+ * the protocol's default rate (Di index = Fi index = 1)
+ */
+ ATR_RATE_USEDEFAULT = 0x01,
+ /*
+ * The reader supports the Di/Fi values that the ICC proposed in its ATR
+ * and no action beyond setting the parameters of the reader is required
+ * (this may be automatic depending on the reader's dwFeatures).
+ */
+ ATR_RATE_USEATR = 0x02,
+ /*
+ * The reader can use the features of the ATR specified. However, it
+ * must change the data rate or frequency that the card is running at to
+ * proceed.
+ */
+ ATR_RATE_USEATR_SETRATE = 0x03
+} atr_data_rate_choice_t;
+
+typedef enum atr_t1_checksum {
+ ATR_T1_CHECKSUM_LRC = 0x00,
+ ATR_T1_CHECKSUM_CRC = 0x01
+} atr_t1_checksum_t;
+
+typedef struct atr_data atr_data_t;
+
+/*
+ * Allocate and free ATR data.
+ */
+extern atr_data_t *atr_data_alloc(void);
+extern void atr_data_free(atr_data_t *);
+
+/*
+ * Reset an allocated ATR data to be ready to parse something else.
+ */
+extern void atr_data_reset(atr_data_t *);
+
+/*
+ * Parse the ATR data into an opaque structure that organizes the data and
+ * allows for various queries to be made on it later.
+ */
+extern atr_parsecode_t atr_parse(const uint8_t *, size_t, atr_data_t *data);
+extern const char *atr_strerror(atr_parsecode_t);
+
+/*
+ * Get an eumeration of supported protocols in this ATR data. Note that if a
+ * reserved protocol is encountered, we may not report it as we don't know of it
+ * at this time.
+ */
+extern atr_protocol_t atr_supported_protocols(atr_data_t *);
+
+/*
+ * Based on the ATR determine what the default protocol is and whether or not it
+ * supports negotiation. When a ICC is not negotiable, it will always start up
+ * with a specific protocol and parameters based on the ATR and be ready to use.
+ * Otherwise, the card will be in a negotiable mode and be set to a default set
+ * of parameters.
+ */
+extern boolean_t atr_params_negotiable(atr_data_t *);
+extern atr_protocol_t atr_default_protocol(atr_data_t *);
+
+/*
+ * Protocol default values.
+ */
+extern uint8_t atr_fi_default_index(void);
+extern uint8_t atr_di_default_index(void);
+
+/*
+ * Obtain the table indexes that should be used by the device.
+ */
+extern uint8_t atr_fi_index(atr_data_t *);
+extern uint8_t atr_di_index(atr_data_t *);
+extern atr_convention_t atr_convention(atr_data_t *);
+extern uint8_t atr_extra_guardtime(atr_data_t *);
+extern uint8_t atr_t0_wi(atr_data_t *);
+extern atr_t1_checksum_t atr_t1_checksum(atr_data_t *);
+extern uint8_t atr_t1_bwi(atr_data_t *);
+extern uint8_t atr_t1_cwi(atr_data_t *);
+extern atr_clock_stop_t atr_clock_stop(atr_data_t *);
+extern uint8_t atr_t1_ifsc(atr_data_t *);
+
+/*
+ * Use this function to determine what set of Di and Fi values should be used by
+ * a reader, based on the parameters from the ATR and the reader's cclass.
+ */
+extern atr_data_rate_choice_t atr_data_rate(atr_data_t *, ccid_class_descr_t *,
+ uint32_t *, uint_t, uint32_t *);
+
+#ifndef _KERNEL
+extern void atr_data_hexdump(const uint8_t *, size_t, FILE *);
+extern void atr_data_dump(atr_data_t *, FILE *);
+#endif
+
+/*
+ * String and table index values.
+ */
+extern const char *atr_protocol_to_string(atr_protocol_t);
+extern uint_t atr_fi_index_to_value(uint8_t);
+extern const char *atr_fi_index_to_string(uint8_t);
+extern const char *atr_fmax_index_to_string(uint8_t);
+extern uint_t atr_di_index_to_value(uint8_t);
+extern const char *atr_di_index_to_string(uint8_t);
+extern const char *atr_clock_stop_to_string(atr_clock_stop_t);
+extern const char *atr_convention_to_string(atr_convention_t);
+
+/*
+ * Functions for generating and testing PPS values. Before calling
+ * atr_pps_fidi_accepted(), one must call atr_pps_valid().
+ */
+#define PPS_BUFFER_MAX 6
+extern uint_t atr_pps_generate(uint8_t *, size_t, atr_protocol_t, boolean_t,
+ uint8_t, uint8_t, boolean_t, uint8_t);
+extern boolean_t atr_pps_valid(void *, size_t, void *, size_t);
+extern boolean_t atr_pps_fidi_accepted(void *, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ATR_H */