?? tlv.c
字號:
/* ============================================================================ Project Name : jayaCard Module Name : proto/bios/lv/tlv.c Version : $Id: tlv.c,v 1.6 2004/01/11 09:56:31 dgil Exp $ Description: TLV (short TLV - tag length value) The Original Code is jayaCard code. The Initial Developer of the Original Code is Gilles Dumortier. Portions created by the Initial Developer are Copyright (C) 2002-2004 the Initial Developer. All Rights Reserved. Contributor(s): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see http://www.gnu.org/licenses/gpl.html History Rev Description 050903 dgil Wrote it from experimental/ber (seek a tag) 081003 dgil More integration from experimental/ber (update, append a tag) ============================================================================*/#include "precomp.h"#ifdef JAYA_TLV/* ============================================================================ Annex D Use of the basic encoding rules of ASN.1 D.1 BER-TLV data object Each BER-TLV data object (see ISO/IEC 8825) shall consist of 2 or 3 consecutive fields : The tag filed T consists of one or more consecutive bytes. It encodes a class, a type and a number. The length field consists of one or more consecutive bytes. It encodes an integer L. If L is not null, then the value field V consists of L consecutive bytes. If L is null, then the data object is empty: there is no value field. ISO/IEC 7816 uses neither '00' nor 'FF' as tag value. NOTE - Before, between or after BER-TLV data objects, '00' or 'FF' bytes without any meaning may occur (e.g. due to erased or modified TLV-coded data objects). D.2 Tag field The bits B8 and B7 of the leading byte of tag field shall encode the tag class, i.e. the class of the data object. B8-7='00' introduces a tag of universal class B8-7='01' introduces a tag of application class B8-7='10' introduces a tag of context-specific class B8-7='11' introduces a tag of private class The bit B6 of the leading byte of the tag field shall encode the tag type, i.e. the type of the data object. B6=0 introduces a primitive data object B6=1 introduces a constructed data object If the bits B5-B1 of the leading byte are not all set to 1, then may they shall encode an integer equal to the tag number which therefore lies in the range from 0 to 30. Then the tag field consists of a single byte. Otherwise (B5-B1 set to 1 in the leading byte), the tag field shall continue on one or more shubsequent bytes. The bit B8 of each subsequent byte shall be set to 1, unless it is the last subsequent byte The bits B7-B1 of the first subsequent byte shall not be all set to 0 The bits B7-B1 of the first subsequent byte, folowed by the bits B7 to B1 of each further subsequent byte, up to and including the bits B7-B1 of the last subsequent byte, shall encode an integer equal to the tag number (thus strictly positive). D.3 Length field In short form, the length field consists of a single byte where the bit B8 shall be set to 0 and the bits B7-B1 shall encode an integer equal to the number of bytes in the value field. Any length from 0-127 can thus be encoded by 1 byte. In long form, the length field consists of a leading byte where the bit B8 shall be set to 1 and the B7-B1 shall not be all equal, thus encoding a positive integer equal to the number of subsequent bytes in the length field. Those subsequent bytes shall encode an integer equal to the number of bytes in the value field. Any length within the APDU limit (up to 65535) can thus be encoded by 3 bytes. NOTE - ISO/IEC 7816 does not use the indefinite lengths specified by the basic encoding rules of ASN.1 (see ISO/IEC 8825). D.4 Value field In this part of ISO/IEC 7816, the value field of some primitive BER-TLV data objects consists of zero, one or more SIMPLE-TLV data objects. The value field of any other primitive BER-TLV data object consists of zero, one or more data elements fixed by the specifications of the data objects. The value field of each constructed BER-TLV data object consists of zero, one or more BER-TLV data objects. ========================================================================= *//* ============================================================================ These functions are using current_EF header to move inside the TLV area base address is : current_EF.u3.body_ef end address is : current_EF.u3.body_ef+current_EF.u4.sizefile In the case JAYA_FILESYSTEM is undefined BUT you want TLV support inside your eeprom area, you need : #define JAYA_TLV to have this module current_EF.u3.body_ef fixed to the base address of your TLV area current_EF.u4.sizefile fixed to the size of your TLV area Also, __tlv_init_area() must be called during the eeprom bootstrap. ========================================================================= *//* ============================================================================ __tlv_size_of_length() ========================================================================= */jbyte __tlv_size_of_length(jword len){ if (len<=127) return 1; if (len<=255) return 2; return 3;}/* ============================================================================ __tlv_init_area() Initialise the file content for TLV management. MUST be called when the file is created to embedded TLV. ========================================================================= */void __tlv_init_area(void){ current_tlv = header_file.u3.body_ef; next_tlv = header_file.u3.body_ef; HAL_ERASE_EEPROM(header_file.u3.body_ef,header_file.u4.sizefile,0xFF); LOG3("TLV","__tlv_init_area(): start=0x%.4X size=%d end=0x%.4X", header_file.u3.body_ef, header_file.u4.sizefile, header_file.u3.body_ef+header_file.u4.sizefile );}/* ============================================================================ __tlv_get_tag() assume: next_tlv is the address of the first byte of a TLV structure update current_tlv_tag, current_tlv_len and current_tlv_val with the current TLV ber. returns: address of the next TLV ber if no error, next_tlv otherwise. ========================================================================= */jword __tlv_get_tag(void){ LOCAL(jbyte,b); LOCAL(jword,adr); current_tlv = next_tlv; adr = current_tlv; if (adr>(current_EF.u3.body_ef+current_EF.u4.sizefile)) { /* hmmm ... */ BIOS_SETERR(ERR_TAG_NOT_FOUND); return next_tlv; }next_byte: /* read the first byte of Tag */ b = HAL_EEPROM_READ_BYTE(adr); adr++; /* invalid Tag ? (could be the end of the used area) */ if ((b==0x00) || (b==0xFF)) { if (adr<=(current_EF.u3.body_ef+current_EF.u4.sizefile)) goto next_byte;invalid: BIOS_SETERR(ERR_INVALID_TAG); return next_tlv; } if ((b&0x1F)==0x1F) { /* tag on next byte */ current_tlv_tag = b; b = HAL_EEPROM_READ_BYTE(adr); adr++; if ((b&0x7F)==0) goto invalid; if ((b&0x80)==0x80) goto invalid; current_tlv_tag = (current_tlv_tag<<8) + b; } else { /* tag on b */ current_tlv_tag = b; } /* read the first byte of Length */ b = HAL_EEPROM_READ_BYTE(adr); adr++; if ((b&0x80)==0x00) { /* short form */ current_tlv_len = (jword)b; } else { /* long form */ if (b==0x81) { /* two bytes */ current_tlv_len = (jword)HAL_EEPROM_READ_BYTE(adr); adr++; } else if (b==0x82) { /* three bytes */ current_tlv_len = HAL_EEPROM_READ_WORD(adr); adr +=2 ; } else { /* limit to 65536 bytes */ BIOS_SETERR(ERR_INVALID_LENGTH); return next_tlv; } } /* next byte is the Value */ current_tlv_val = adr; return adr+current_tlv_len;}/* ============================================================================ __tlv_seek_first_tag() Seek the first occurence of a tag in the current EF body content update current_tlv, current_tlv_tag, current_tlv_len and current_tlv_val with the found TLV ber. return jtrue if the tag has been found, jfalse otherwise. ========================================================================= */#ifdef JAYACFG_DO_NOT_SUPPORT_RETURNTYPE_JBOOLjbyte __tlv_seek_first_tag(jword tag)#elsejbool __tlv_seek_first_tag(jword tag)#endif{ next_tlv = current_EF.u3.body_ef; LOG1("TLV","__tlv_seek_first_tag(): tag = %.4X",tag); return __tlv_seek_next_tag(tag);}/* ============================================================================ __tlv_seek_next_tag() Seek the next occurence of a tag in the current EF body content
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -