acsigon関係のファイルコミット忘れを修正。

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@320 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
yosiokat 2007-12-06 05:07:19 +00:00
parent c6cf2021d4
commit 9d06eb337b
7 changed files with 2120 additions and 0 deletions

View File

@ -0,0 +1,667 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - tools - makerom.TWL
File: ber.h
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/* $Id$ */
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#ifndef HEADER_COMMON_BER_H
#define HEADER_COMMON_BER_H
#ifdef __cplusplus
extern "C" {
#endif
//#include "r_com.h" // local modified.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* The ASN.1 types are in this file */
#include "ber_type.h"
#if defined(VXWORKS) && defined(m_len)
#undef m_len
#endif
/* In the info field */
/**
* The name-space of the object is universal or global.
*/
#define BER_UNIVERSAL 0x00
/**
* The name-space of the object is application specific.
*/
#define BER_APPLICATION 0x40
/**
* The name-space of the object is context specific.
* Context-specific items are constructed types of a value (cont [1]).
*/
#define BER_CONTEXT_SPECIFIC 0x80
/**
* The name-space of the object is private.
*/
#define BER_PRIVATE 0xc0
/**
* Masks the class part of the type of the BER item.
*/
#define BER_CLASS_MASK 0xc0
/**
* The items has no explicit data. All following items that fit in the length
* of the constructed item are part of the data. If the constructed item is
* indefinite encoded, the data finishes with an EOC of 0 length.
* The items that make up the data of this item are said to have a greater
* depth than the constructed item.
*/
#define BER_CONSTRUCTED 0x20
/**
* This mask is used to determine the type of the item.
*/
#define BER_PRIMITIVE_TAG_MASK 0x1f
/* Set in the flags */
/**
* Flag indicates that the stack of items was dynamically allocated and needs
* to be freed.
*/
#define BER_FLAG_DYNAMIC 0x01
/**
* Flag indicates that the items in the #BER_ITEMS_SK were dynamically allocated
* and need to be freed.
*/
#define BER_FLAG_DYNAMIC_ITEMS 0x02
/**
* A prefix byte has been set. A bit string requires a byte to precede the data
* in order to provide information about the number of valid bits.
*/
#define BER_FLAG_PREFIX_BYTE 0x04
/**
* The item has an invalid length value associated with it. This may be because
* the length is greater than the parent's length or because the item has a
* that is required more than five bytes to represent.
*/
#define BER_FLAG_INVALID_LENGTH 0x08
/**
* The header bytes have been seen for this item and any parents will not have
* these bytes available.
*/
#define BER_FLAG_SEEN_HEADER 0x10
/**
* No data for this item has been made available.
*/
#define BER_FLAG_NO_DATA_SEEN 0x20
/**
* Set if the header of the BER_ITEM has already been encoded.
*/
#define BER_FLAG_HEADER_ENCODED 0x40
/**
* @fn int BER_prefix_byte(BER_ITEMS *i)
*
* Returns whether the prefix byte flag has been set for this item.
*
* @param i [In] BER item.
* @return Bit is set.
* <li>0 = False, the bit is not set.</li>
* <li>1 = True, the bit is set.</li>
*
* @note This flag is used for the bit string type as it requires an extra
* byte to indicate a number of valid bits.
*
* @see BER_ITEM_set_prefix_byte().
*/
#define BER_prefix_byte(i) ((i)->flags & BER_FLAG_PREFIX_BYTE)
/**
* @fn int BER_invalid_length(BER_ITEMS *i)
*
* Returns whether the invalid length flag has been set for this item.
*
* @param i [In] BER item.
* @return Bit is set.
* <li>0 = False, the bit is not set.</li>
* <li>1 = True, the bit is set.</li>
*/
#define BER_invalid_length(i) ((i)->flags & BER_FLAG_INVALID_LENGTH)
/* In the info field */
/**
* Mask off the flags of the information field.
*/
#define BER_INFO_MASK 0x0f
/**
* The encoding is BER rather than DER.
*/
#define BER_BER 0x01
/**
* The item is indefinite length encoded. This means that there is no length
* value that can be used to determine the length of the data for this item.
*/
#define BER_ILEN 0x02
/**
* The contents of this item are to be hidden.
*/
#define BER_HIDE_CONTENTS 0x04
/**
* The header of this item has not been set yet.
*/
#define BER_NO_HEADER 0x08
/**
* @fn int BER_hide_contents(BER_ITEMS *i)
*
* Returns whether the hide contents flag has been set for this item.
*
* @param i [In] BER item.
* @return Bit is set.
* <li>0 = False, the bit is not set.</li>
* <li>1 = True, the bit is set.</li>
*/
#define BER_hide_contents(i) ((i)->info & BER_HIDE_CONTENTS)
/**
* @fn int BER_no_header(BER_ITEMS *i)
*
* Returns whether the no header flag has been set for this item.
*
* @param i [In] BER item.
* @return Bit is set.
* <li>0 = False, the bit is not set.</li>
* <li>1 = True, the bit is set.</li>
*
* @note This could be set when the data has been placed in the item but the
* header has not been setup.
*/
#define BER_no_header(i) ((i)->info & BER_NO_HEADER)
/**
* @fn unsigned long BER_MASK(int a)
*
* Returns the BER type as a bit mask.
*
* @param a [In] Type of the item.
* @return Each ASN.1 type maps to a bit in a 32 bit value.
*
* @note There are less than 32 primative ASN.1 types. This
* means a 32bit word can be used to specify acceptable 'types'.
*/
#define BER_MASK(a) (1UL << (a))
/**
* @fn int BER_constructed(BER_ITEMS *a)
*
* Returns a value to indicate that the item is constructed.
*
* @param a [In] BER item.
* @return Constructed bit set.
* <li>0 = False, the bit is not set.</li>
* <li>#BER_CONSTRUCTED = True, the bit is set.</li>
*/
#define BER_constructed(a) (((a)->info) & BER_CONSTRUCTED)
/**
* @fn int BER_class(BER_ITEMS *a)
*
* Returns a value to indicate the name-space of the item.
*
* @param a [In] BER item.
* @return Application and/or context specific bit set.
* <li>#BER_UNIVERSAL = Universal.</li>
* <li>#BER_APPLICATION = application specific item.</li>
* <li>#BER_CONTEXT_SPECIFIC = context specific item.</li>
* <li>#BER_PRIVATE = private item.</li>
*
* @note The top two bits of the type are used to specify the name-space of
* the item and these are pulled out and put in the info field.
*/
#define BER_class(a) (((a)->info) & BER_CLASS_MASK)
/**
* @fn int BER_indefinite_encoding(BER_ITEMS *a)
*
* Returns a value to indicate if the item is indefinite encoded. That is,
* the number of bytes to the data is not known.
*
* @param a [In] BER item.
* @return Indefinite length bit set.
* <li>0 = False, the bit is not set.</li>
* <li>#BER_ILEN = True, the bit is set.</li>
*/
#define BER_indefinite_encoding(a) (((a)->info) & BER_ILEN)
/**
* @fn void BER_ITEMS_SK_clear(BER_ITEMS_SK *sk)
*
* Clears the items out of the stack.
*
* @param sk [In] Stack of BER items.
*
* @note The items in the stack are not freed by this call.
*/
#define BER_ITEMS_SK_clear(sk) ((sk)->num=0)
/**
* Maximum length of the tag/type of an item.
*/
#define BER_MAX_TAG_LEN_IN_BITS (sizeof(int) * 8)
/**
* Minumum length of the data for a header of an item that streaming can use
* when decoding.
*/
#define BER_MIN_HEADER_LEN 2
/**
* Maximum length of the header of an item.
*/
#define BER_MAX_HEADER_LEN (1 + (BER_MAX_TAG_LEN_IN_BITS / 8) + \
1 + sizeof(unsigned long))
#ifndef NO_STREAM
/**
* The initial state in which a new item is created.
*/
#define BER_STATE_READ_NEXT_ITEM 1
/**
* The state in which the item header is read in and processed.
*/
#define BER_STATE_READ_NEXT_ITEM_HEADER 2
/**
* The state in which the data of the item is read in and processed.
*/
#define BER_STATE_READ_NEXT_ITEM_DATA 3
/**
* The state in which the current item is the last for the constructed item
* above.
*/
#define BER_STATE_GO_UP 4
#endif /* !NO_STREAM */
/**
* This structure holds the information about the data part of the BER item.
*/
typedef struct ber_bytes_st
{
/**
* Length of the data for this item.
*/
unsigned long len;
/**
* A pointer to the start of the valid data of this item.
*/
unsigned char *bytes;
} BER_BYTES;
/**
* This structure holds the information about the data part of the BER item.
*/
typedef struct ber_item_st
{
/**
* The data of the item.
*/
BER_BYTES data;
#ifndef NO_STREAM
/**
* The depth of this item. The depth is the number of constructed items this
* item is under.
*/
unsigned char depth;
/**
* The header bytes of the item. They are kept as the buffer it comes from
* may no longer be valid when the header data is needed.
*/
unsigned char header[BER_MAX_HEADER_LEN];
/**
* Number of data bytes seen of this item. When streaming the number of
* bytes seen depends on the number of bytes in the buffer that is being
* parsed.
*/
unsigned long seen;
/**
* Number of data bytes left to get out. When streaming the number of
* valid bytes available depends on the number of bytes in the buffer that
* is being parsed.
*/
unsigned long part_len;
/**
* Number of data bytes already encoded of the BER_ITEM. When
* streaming the number of bytes encoded depends on how much space
* is in the output buffer and how many bytes are available to encode.
*/
unsigned int encoded;
#endif /* !NO_STREAM */
/**
* The tag number that indicates the type of the item.
*/
unsigned int type;
/**
* Information about the item. Includes the name-space, constructed bit
* and whether it is indefinite encoded.
*/
unsigned char info;
/**
* The length of the header bytes. Varies depending on name-space and the
* number of bytes needed to represent data length.
*/
unsigned char hlen;
/**
* The extra flags of the item. Includes flags to indicate what parts of the
* item are dynamic.
*/
unsigned char flags;
/**
* Holds an 'extra' prefix byte. Needed for the bit string type as it
* requires an extra byte to indicate the number of valid bits in the data.
*/
unsigned char prefix_byte;
} BER_ITEM;
/**
* An item and pointer to other items linked to it.
*/
typedef struct ber_items_st
{
/**
* The current item data.
*/
BER_ITEM item;
/**
* The constructed item that this item is the data for.
*/
struct ber_items_st *parent;
/**
* The next item that is also in this constructed item.
*/
struct ber_items_st *next;
/**
* When the item is constructed, this points to the first item that is
* part of the data for this item.
*/
struct ber_items_st *down;
} BER_ITEMS;
/**
* Stack of BER items. The stack is the context of the BER items.
*/
typedef struct ber_items_sk_st
{
/**
* The number of items stored in the stack.
*/
unsigned int num;
/**
* The maximum number of items that can be stored in the stack.
*/
unsigned int max;
/**
* The array of items.
*/
BER_ITEMS *items;
/**
* Flags of the structure. Includes dynamic allocation of data.
* If the data is dynamic, this means that it can grow.
*/
unsigned int flags;
#ifndef NO_STREAM
/**
* Current streaming parsing state.
*/
int state;
/**
* Current item is indefinite encoded.
*/
int inf;
/**
* The parent or the constructed item this item belongs to is indefinite
* encoded.
*/
int pinf;
/**
* The current item is a constructed item.
*/
int con;
/**
* The next item needs to be placed under the current item.
* Alternatively, the previous item was a constructed item.
*/
int down;
/**
* The index into the array of items of the current item.
* Due to the fact that the items may be reallocated an index needs to be
* kept rather than a pointer.
*/
int this_idx;
/**
* The index into the array of items of the next/new item.
* Due to the fact that the items may be reallocated an index needs to be
* kept rather than a pointer.
*/
int next_idx;
/**
* Holds a pointer to the next/new item for the next call to the streaming
* parsing function.
*/
BER_ITEMS *next;
#endif /* !NO_STREAM */
} BER_ITEMS_SK;
/**
* @fn unsigned int BER_ITEMS_SK_num(BER_ITEMS_SK *sk)
*
* Returns the number of items in the stack.
*
* @param sk [In] Stack of BER items.
* @return Number of items in the stack.
*
* @note Useful in calculating the index of the next new item.
*/
#define BER_ITEMS_SK_num(sk) ((sk)->num)
/**
* @fn unsigned BER_ITEMS *BER_ITEMS_SK_items(BER_ITEMS_SK *sk, unsigned int n)
*
* Returns a pointer to a data item in the stack.
*
* @param sk [In] Stack of BER items.
* @param n [In] Array position of the item to obtain.
* @return Pointer to a BER item.
*/
#define BER_ITEMS_SK_items(sk,n) (&((sk)->items[n]))
/**
* Return value indicating no error occurred.
*/
#define BER_OK 0
/**
* Return value indicating no error occurred.
*/
#define BER_ERR_OK 0
/**
* Error indicating that the type/tag of the item was too long.
* This normally indicates that the encoding is invalid.
* Some valid private name-space items may cause this error.
*/
#define BER_ERR_TAG_TOO_LONG 1
/**
* Error indicating that there are not enough bytes in the buffer to complete
* the message. This is not a fatal error when streaming.
*/
#define BER_ERR_NOT_ENOUGH_BYTES 2
/**
* Error indicating that the value of the length of data is too long.
* A length value can be infinitely long but only lengths that can fit in an
* <i>unsigned long</i> are supported.
*/
#define BER_ERR_LENGTH_TOO_LARGE 3
/**
* Error indicating that the item is not constructed as expected or required.
*/
#define BER_ERR_NOT_CONSTRUCTED 4
/**
* Error indicating that the function was unable to allocate the memory
* required.
*/
#define BER_ERR_OUT_OF_MEMORY 5
/**
* Error indicating that the function needed space for more items but was
* unable to grow the stack. This is mostly likely to occur when the array
* of items is static and more items than allocated are required.
*/
#define BER_ERR_OUT_OF_ITEMS_STORAGE 6
/**
* Error indicating that the comparison of the tag/type failed.
*/
#define BER_ERR_CMP_TAG 7
/**
* Error indicating that the item is not an integer as expected or required.
*/
#define BER_ERR_NOT_AN_INTEGER 8
/**
* Error indicating that the length of the data is too large to return in an
* <i>unsigned long</i>.
*/
#define BER_ERR_NUMBER_TOO_LARGE 9
/**
* Error indicating that the bytes of data did not match in the comparison.
*/
#define BER_ERR_CMP_BYTES 10
/**
* Error indicating an end of content item is present when not in an indefinite
* encoded item. Normally occurs when buffer is not filled properly.
*/
#define BER_ERR_UNEXPECTED_EOC 11
/**
* Error indicating that the value of the length is invalid. This occurs when
* the length is an indefinite length value and the item is not constructed.
*/
#define BER_ERR_INVALID_LENGTH_ENCODING 12
/**
* Error indicating that the partial length of the value is not zero. This
* means that there is data in the items that has not been used yet that will
* be invalidated by parsing the new data. Streaming only.
*/
#define BER_ERR_PARTIAL 13
/**
* Error indicating that the various length fields of a BER_ITEM do
* not make sense and therefore processing cannot continue. In this
* case an unidentified logic error earlier in the code has occured.
*/
#define BER_ERR_PAR_ENC_LENGTH 14
/**
* Invalid state in parsing or encoding.
*/
#define BER_ERR_INVALID_STATE 15
/* A description of the BER item header:
* First byte definition
* 5 1 - search for a class
* 0 - search for a number
* for class
* 7-6 - for class, it class field
* 4-0 - tag, normal taging convention
* for number
* 7-6 - 0 - do next operation
* - 0x40 - finished
* - 0x80 - operate on the contents of this item
* - 0xc0 - operate on the contents and return at end
* 4-0 - num to scan, can only do 31 at a time, extend with subsequent calls
* Number counts skip explicit and implicit tags, they only count on
* universal types.
* If bit 5 is set, and 6-7 are 0, then we have 'special' comands
* which we can use WRT class elements.
* These two are needed when we are 'sitting' on a non-primative tag
* item since the normal 'counting' commands will skip the element before
* they perform their command.
* 0x20 return
* 0x21 operate on the contents
*/
/* To get a public key and the algorithm the following strings would work
* 0x80|0,0x40|5 - this will return the pubkey structure
* 0x80,0xc0 - Return the pubkey algorithm (from the pubkey)
* 0x80,0xc1 - Return the pubkey parameters
* 0x81 - Return the pubkey bitstring
* 0x80,0x20|0x80|3,0xc0 - return the first extension
*/
int BER_read_item(BER_ITEM *item,unsigned char *p,unsigned long max);
int BER_find(BER_ITEM *ret,BER_ITEM *in,unsigned char *find);
int BER_ITEMS_SK_get(BER_ITEMS_SK *sk,int *items_idx);
void BER_ITEMS_append(BER_ITEMS *a,BER_ITEMS *b);
int BER_ITEMS_under(BER_ITEMS *a,BER_ITEMS *b);
int BER_ITEMS_SK_grow(BER_ITEMS_SK *ks,unsigned int num);
int BER_parse(BER_ITEMS_SK *ks,unsigned char *in,unsigned long max,
unsigned long *num_used);
int BER_parse_stream(BER_ITEMS_SK *ks,unsigned char **in,long mlen,
long *num_used);
#ifdef HEADER_COMMON_BIO_H
int BER_print(BIO *bio,BER_ITEMS *items);
int BER_out(BIO *out,BER_ITEMS *start);
#else /* !HEADER_COMMON_BIO_H */
int BER_print(char *,BER_ITEMS *items);
int BER_out(char *out,BER_ITEMS *start);
#endif /* !HEADER_COMMON_BIO_H */
void BER_ITEM_init(BER_ITEM *item);
void BER_ITEMS_init(BER_ITEMS *item);
void BER_ITEM_set_all(BER_ITEM *item,unsigned int sclass,unsigned int tag,
unsigned char *data,unsigned int len,unsigned int info, unsigned int flags);
void BER_ITEM_set_header(BER_ITEM *item, unsigned int sclass,unsigned int tag,
unsigned int flags);
void BER_ITEM_set_data(BER_ITEM *item, unsigned char *data, unsigned int len);
int BER_ITEM_cmp_tag(BER_ITEM *a,unsigned int tag);
int BER_ITEM_get_long(BER_ITEM *a,long *l);
int BER_ITEM_set_long(BER_ITEM *a, long lret, unsigned char *buf);
size_t BER_ITEM_header_len(BER_ITEM *item);
unsigned int BER_ITEM_header_write(BER_ITEM *item, unsigned char *out);
unsigned int BER_ITEM_header_swrite(BER_ITEM *item, unsigned char *out);
int BER_ITEM_cmp_bytes(BER_ITEM *a,unsigned char *d, unsigned int l);
void BER_ITEMS_SK_init(BER_ITEMS_SK *sk,BER_ITEMS *items,unsigned int num,
unsigned int max);
void BER_ITEMS_SK_free(BER_ITEMS_SK *sk);
unsigned long BER_ITEMS_recalc_length(BER_ITEMS *a);
int BER_ITEMS_encode(BER_ITEMS *a, unsigned char *out, unsigned long *olen,
unsigned long max);
int BER_ITEMS_encode_stream(BER_ITEMS **a, unsigned char *out,
unsigned long *olen, unsigned long max);
int BER_load_level(BER_ITEMS_SK *sk, unsigned char *ino, unsigned long m_len);
/* We have to make the second parameter 'unsigned int' instead of
* 'unsigned char' because both the Sun and HP compilers complain
* when using a mix of ANSI prototypes and K&R function implementations
*/
void BER_ITEM_set_prefix_byte(BER_ITEM *item, unsigned int byte);
/* Used to count bits in an array of chars, strip leading 0, counts bits */
int R_num_bits(unsigned char *buf, int len, int bigendian);
#ifdef __cplusplus
}
#endif
#endif /* !HEADER_COMMON_BER_H */

View File

@ -0,0 +1,62 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - tools - makerom.TWL
File: ber_lcl.h
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/* $Id$ */
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#ifndef HEADER_COMMON_BER_LCL_H
#define HEADER_COMMON_BER_LCL_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef STANDALONE
#include "r_com.h"
#else
#include <stdio.h>
#include <stdlib.h>
#define NO_STDLIB_MAPPING
#include "acmemory.h"
#define Malloc(a) ACMemory_Alloc(a)
#define Free(a) ACMemory_Free(a)
#define Memset(a,b,c) ACMemory_Memset(a,b,c)
#define Memcpy(a,b,c) ACMemory_Memcpy(a,b,c)
#define Realloc(a,b,c) ACMemory_Realloc(a,b,c)
#define Memcmp(a,b,c) memcmp(a,b,c)
#define Bsearch(a,b,c,d,e) bsearch(a,b,c,d,e)
#endif
#include "ber.h"
#ifdef UNDER_CE
#include "wcestdlb.h" /* include for bsearch */
#endif
#ifdef __cplusplus
}
#endif
#endif /* !HEADER_COMMON_BER_H */

View File

@ -0,0 +1,221 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - tools - makerom.TWL
File: ber_type.h
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/* $Id$ */
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
/**
* @file
* This file contains information on the ASN.1 types used to perform
* Basic Encoding Rules (BER) encoding and decoding operations.
*/
#ifndef HEADER_COMMON_BER_TYPE_H
#define HEADER_COMMON_BER_TYPE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* Indicates the end of content for encoded items with an unspecified length.
*/
#define BER_EOC 0
/**
* Indicates either "true" or "false" as per the ASN.1 boolean values
* #BER_TRUE and #BER_FALSE.
*/
#define BER_BOOLEAN 1
/**
* Effectively unbounded but commonly used to hold values
* that will fit into a <tt>long</tt>.
*/
#define BER_INTEGER 2
/**
* An array of Bytes in which the first Byte is the number of bits to
* discard from the end.
*/
#define BER_BIT_STRING 3
/**
* An 8-bit (hexadecimal Byte) array or Byte array.
*/
#define BER_OCTET_STRING 4
/**
* A Basic Encoding Rules (BER) object that has no data. It is used when data
* is specified for a general case but not a specific case.
*/
#define BER_NULL 5
/**
* A Basic Encoding Rules (BER) object used to hold an ASN.1 identifier that
* describes the make-up of the rest of the constructed elements.
*/
#define BER_OBJECT 6
/**
* An indefinitely long string of characters (plus space) used to describe an
* object.
*/
#define BER_OBJECT_DESCRIPTOR 7
/**
* Embedded material that is not defined using ASN.1, such as a GIF file. This
* type is deprecated in favour of #BER_EMBEDDED_PDV.
*/
#define BER_EXTERNAL 8
/**
* A comma-separated list of three integers for the mantissa, the base
* (2 or 10), and the exponent. (Also <tt>PLUS-INFINITY</tt> and
* <tt>MINUS-INFINITY</tt>.) <br>
* Hence, <tt>{x, y, z}</tt> is <tt>(x times (y to the power z))</tt>,
* where <tt>y</tt> is allowed to take only the values 2 and 10.
*/
#define BER_REAL 9
/**
* A comma-separated list of names.
*/
#define BER_ENUMERATED 10
/**
* Embedded material that is not defined using ASN.1, such as a GIF file. This
* type supercedes #BER_EXTERNAL.
*/
#define BER_EMBEDDED_PDV 11
/**
* A character string which may contain characters from any language.
*/
#define BER_UTF8STRING 12
/**
* A constructed type that is used to hold an ordered list of elements.
*/
#define BER_SEQUENCE 16
/**
* A constructed type that is used to hold a list of repeating elements.
*/
#define BER_SET 17
/**
* A string of characters containing the digits zero to 9 and space.
*/
#define BER_NUMERICSTRING 18
/**
* A character array that only allows a small subset of values, namely
* [A-Z] [a-z] [0-9] and [ '()+,-./:=?].
*/
#define BER_PRINTABLESTRING 19
/**
* A deprecated synonym for #BER_TELETEXSTRING.
*/
#define BER_T61STRING 20
/**
* A character string that allows register entries 6, 87, 102, 103, 106, 107,
* 126, 144, 150, 153, 156, 164, 165 and 168 (plus space and delete)
* of the International Register of Coded Character Sets.
*/
#define BER_TELETEXSTRING 20
/**
* A character string that enables access to the "characters" used to
* build crude pictures on videotext systems.
*/
#define BER_VIDEOTEXSTRING 21
/**
* A character string that allows the register entries 1 and 6 (plus space and
* delete) of the International Register of Coded Character Sets to be used
* with escape sequences.
*/
#define BER_IA5STRING 22
/**
* A character string representing the date and time in the format: <br>
* <tt>ddmmyyhhmmssZ</tt>.
*/
#define BER_UTCTIME 23
/**
* A character string representing the date and time in the format: <br>
* <tt>ddmmyyyyhhmmssZ</tt>.
*/
#define BER_GENERALIZEDTIME 24
/**
* A character string that allows any of the register entries in the
* International Register for printable characters other than
* the control character entries.
*/
#define BER_GRAPHICSTRING 25
/**
* A deprecated synonym for #BER_VISIBLESTRING.
*/
#define BER_ISO64STRING 26
/**
* A character string that allows register entry 6 of the International
* Register of Coded Character Sets to be used with escape sequences.
*/
#define BER_VISIBLESTRING 26
/**
* A character string that allows any of the register entries in the
* International Register for printable characters.
*/
#define BER_GENERALSTRING 27
/**
* A character string which may contain characters from any language
* without using combining characters.
*/
#define BER_UNIVERSALSTRING 28
/**
* A character string which may contain characters from any living
* language.
*/
#define BER_BMPSTRING 30
/** The boolean value "false" for the #BER_BOOLEAN ASN.1 type. */
#define BER_FALSE 0
/** The boolean value "true" for the #BER_BOOLEAN ASN.1 type. */
#define BER_TRUE 255
#ifdef __cplusplus
}
#endif
#endif /* !HEADER_COMMON_BER_TYPE_H */

View File

@ -0,0 +1,187 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <sysmenu/acsign.h>
#include "acmemory.h"
#include "ber.h"
// SHA1
#include "sha.h"
#define _DLENGTH_ (160/8)
#define _BLENGTH_ (512/8)
#define HASHContext SHA_CTX
#define HASHReset( _context ) (void)SHA1_Init( _context )
#define HASHSetSource( _context, _ptr, _len ) (void)SHA1_Update( _context, _ptr, _len )
#define HASHGetDigest( _context, _ptr ) (void)SHA1_Final( _ptr, _context )
// BN
#include "bn.h"
#include "bn_lcl.h"
#define BER_NULL 5
#define BER_OBJECT 6
#define BER_SEQUENCE 16
#define BER_OCTET_STRING 4
#define BER_CONSTRUCTED 0x20
// RSAキー構成要素のパラメータ
typedef struct KeyParam {
u8 *pData;
int length;
}KeyParam;
static BOOL GetRSAPrivateKeyParam( const u8 *pKeyDER, KeyParam *pMod, KeyParam *pPrvExp );
//
// rsa_padding_add_pkcs1_type_1関数相当
//
static int add_padding(unsigned char *out,
int out_len, const unsigned char *in, int in_len)
{
unsigned char *p;
int j,i;
if ((in_len+11) > out_len)
return(1);
/* First we copy data bytes to the output buffer, this
* way the input and output buffers can be the same
* and things will still work */
p=out+out_len-in_len;
for (i=in_len-1; i>=0; i--)
p[i]=in[i];
p=out;
*(p++)=0;
*(p++)=1; /* Private Key BT (Block Type) */
/* pad with 0xff data */
j=out_len-3-in_len;
Memset(p,0xff,(u32)j);
p[j]='\0';
return(0);
}
//
// RSA
//
#define ACS_ENCRYPTED_SIGN_LEN 128
BOOL ACSign_Encrypto(void *sign, const void *key, const void *data, int length)
{
BN_CTX *ctx;
BIGNUM src, dst, exp, mod;
u8 buf[ACS_ENCRYPTED_SIGN_LEN];
int len = length;
BOOL result = TRUE;
KeyParam key_mod;
KeyParam key_prvExp;
if (NULL == sign || NULL == key || NULL == data || 0 > length) {
return FALSE;
}
if( !GetRSAPrivateKeyParam( key, &key_mod, &key_prvExp ) ) {
OS_TPrintf( "RSA PrivKey Param get failed.\n" );
return FALSE;
}
if ( add_padding( buf, ACS_ENCRYPTED_SIGN_LEN, data, length ) ) {
OS_TPrintf("encode_padding was failed.\n");
result = FALSE;
goto end;
}
ctx = BN_CTX_new();
BN_init(&src);
BN_init(&dst);
BN_init(&exp);
BN_init(&mod);
BN_bin2bn((u8*)buf, ACS_ENCRYPTED_SIGN_LEN, &src);
BN_bin2bn(key_prvExp.pData, key_prvExp.length, &exp);
BN_bin2bn(key_mod.pData, key_mod.length, &mod);
BN_mod_exp( &dst, &src, &exp, &mod, ctx );
{ // BIGNUMは最上位が"0"の時、長さが減らされるので、あらかじめ調整しておく
u8 *pSign = sign;
int padLen = ACS_ENCRYPTED_SIGN_LEN - BN_num_bytes( &dst );
while( ( padLen > 0 ) && ( padLen < ACS_ENCRYPTED_SIGN_LEN ) ) {
*pSign++ = 0;
padLen--;
}
len = BN_bn2bin( &dst, pSign );
}
BN_free(&src);
BN_free(&dst);
BN_free(&exp);
BN_free(&mod);
if (ctx) {
BN_CTX_free(ctx);
}
if ( len > ACS_ENCRYPTED_SIGN_LEN ) { // サイズチェック。
OS_TPrintf( "len = %d\n", len );
result = FALSE;
goto end;
}
end:
return result;
}
// DERフォーマットのRSA PublicKeyからパラメータを取得
static BOOL GetRSAPrivateKeyParam( const u8 *pKeyDER, KeyParam *pMod, KeyParam *pPrvExp )
{
BOOL retval = FALSE;
BER_ITEMS_SK sk;
BER_ITEMS *bi;
BER_ITEM item;
// 先頭アイテムから、ファイル全体のサイズを算出
if( BER_read_item( &item, (unsigned char *)pKeyDER, 16 ) ) {
return FALSE;
}
BER_ITEMS_SK_init( &sk, NULL, 0, 0 );
if( BER_parse( &sk, (unsigned char *)pKeyDER, item.data.len + item.hlen, NULL ) == BER_OK ) {
bi = BER_ITEMS_SK_items( &sk, 2 ); // mod
pMod->pData = bi->item.data.bytes;
pMod->length = (int)bi->item.data.len;
bi = BER_ITEMS_SK_items( &sk, 4 ); // private exp
pPrvExp->pData = bi->item.data.bytes;
pPrvExp->length = (int)bi->item.data.len;
retval = TRUE;
}
BER_ITEMS_SK_free( &sk );
return retval;
}

View File

@ -0,0 +1,295 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - tools - makerom.TWL
File: ber_isk.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/* $Id$ */
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "ber_lcl.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BER_ITEMS_SK_INIT
#define SPLIT_BER_ITEMS_SK_GET
#define SPLIT_BER_ITEMS_APPEND
#define SPLIT_BER_ITEMS_UNDER
#define SPLIT_BER_ITEMS_SK_GROW
#define SPLIT_BER_ITEMS_SK_FREE
#endif /* NO_SPLIT */
/* BER_ITEMS_SK_EXPAND_COUNT - number of items to expand to given that
* there are "X" items currently.
*
* note: each item typically costs 28 bytes so 20 is around .5k which
* is a reasonable growth size
*/
#define BER_ITEMS_SK_EXPAND_COUNT(X) ((X)+20)
#ifdef SPLIT_BER_ITEMS_SK_INIT
/**
* Initialises the stack of BER items. The array of items, the current number
* of items and the maximum number of items allocated may be set.
*
* @param sk [In] A stack of BER items.
* @param items [In] An array of BER items.
* @param num [In] The number of BER items in the array.
* @param max [In] The number of BER items allocated in the array.
*/
void BER_ITEMS_SK_init(BER_ITEMS_SK *sk, BER_ITEMS *items, unsigned int num,
unsigned int max)
{
sk->num=num;
sk->max=max;
if (items == NULL)
{
sk->flags=BER_FLAG_DYNAMIC_ITEMS;
}
else
{
sk->flags=0;
}
sk->items=items;
#ifndef NO_STREAM
sk->state=BER_STATE_READ_NEXT_ITEM;
sk->inf=0;
sk->pinf=0;
sk->con=0;
sk->down=1;
sk->this_idx=-1;
sk->next=NULL;
#endif /* !NO_STREAM */
}
#endif /* SPLIT_BER_ITEMS_SK_INIT */
#ifdef SPLIT_BER_ITEMS_SK_GET
/**
* Obtains the next available BER item in the stack.
*
* @param sk [In] Stack of BER items.
* @param index [Out] Index into array of new item.
* @return Indication of successful completion of function.
* Values are:
* <li>0 indicates the function succeeded.</li>
* <li>>0 indicates the function failed.</li>
*
* @note If there is no item available in the array then the array is grown.
* This means that an existing external pointer to an item may not be
* valid after a call to this function.
*/
int BER_ITEMS_SK_get(BER_ITEMS_SK *sk, int *index)
{
int ret; /* return value */
BER_ITEMS *it; /* next item */
/* Ensure there are enough spare items. */
if (sk->num >= sk->max)
{
/* Reallocate the array. */
ret = BER_ITEMS_SK_grow(sk, BER_ITEMS_SK_EXPAND_COUNT(sk->num));
if (ret != 0)
{
return(ret);
}
}
/* Set the new item index for return. */
*index = (int)sk->num;
/* Initialize the new item. */
it = &(sk->items[sk->num++]);
Memset((char *)it, 0, sizeof(BER_ITEMS));
/* return success */
return(0);
}
#endif /* SPLIT_BER_ITEMS_SK_GET */
#ifdef SPLIT_BER_ITEMS_APPEND
/**
* Places the BER item <i>b</i> next to the BER item <i>a</i> in the tree
* structure.
*
* @param a [In] A BER item.
* @param b [In] A BER item.
*/
void BER_ITEMS_append(a,b)
BER_ITEMS *a,*b;
{
b->parent=a->parent;
if (b->parent != NULL)
{
b->parent->item.flags|=BER_FLAG_INVALID_LENGTH;
}
b->next=a->next;
a->next=b;
}
#endif /* SPLIT_BER_ITEMS_APPEND */
#ifdef SPLIT_BER_ITEMS_UNDER
/**
* Places the BER item <i>b</i> below the BER item <i>a</i> in the tree
* structure.
*
* @param a [In] A BER item.
* @param b [In] A BER item.
*
* @return An indication of success:<br>
* <li>0 indicates success</li>
* <li>>0 indicates failure</li>
*/
int BER_ITEMS_under(BER_ITEMS *a, BER_ITEMS *b)
{
if (!(BER_constructed(&a->item) || BER_hide_contents(&a->item)))
{
return(BER_ERR_NOT_CONSTRUCTED);
}
b->parent=a;
b->next=a->down;
a->down=b;
a->item.flags|=BER_FLAG_INVALID_LENGTH;
return(0);
}
#endif /* SPLIT_BER_ITEMS_UNDER */
#ifdef SPLIT_BER_ITEMS_SK_GROW
/**
* Grows the number of allocated BER items.
*
* @param sk [In] A stack of BER items.
* @param num [In] The number of BER items to allocate.
*
* @return An indication of success:<br>
* <li>0 indicates success</li>
* <li>>0 indicates failure</li>
*/
int BER_ITEMS_SK_grow(BER_ITEMS_SK *sk, unsigned int num)
{
int ptr_fix;
unsigned int i;
unsigned int j;
BER_ITEMS *nai;
BER_ITEMS *oai;
BER_ITEMS *oend;
if (num <= sk->num)
{
return(0);
}
if (sk->flags & BER_FLAG_DYNAMIC_ITEMS)
{
if (sk->items == NULL)
{
ptr_fix=0;
nai=(BER_ITEMS *)Malloc(sizeof(BER_ITEMS)*num);
if (nai == NULL)
{
return(BER_ERR_OUT_OF_MEMORY);
}
Memset(nai,0,sizeof(BER_ITEMS)*num);
}
else
{
ptr_fix=1;
nai=(BER_ITEMS *)Realloc(sk->items, sizeof(BER_ITEMS)*num,
sizeof(BER_ITEMS)*sk->max);
if (nai == NULL)
{
return(BER_ERR_OUT_OF_MEMORY);
}
Memset(&(nai[sk->max]),0, sizeof(BER_ITEMS)*(num-sk->max));
}
if (nai == NULL)
{
return(BER_ERR_OUT_OF_MEMORY);
}
/* If we have realloced, and the Memory has moved, we
* need to fix the pointers */
if ((sk->items != nai) && ptr_fix)
{
oai=sk->items;
oend= &(sk->items[sk->num]);
for (i=0; i<sk->num; i++)
{
if ((nai[i].parent >= oai) &&
(nai[i].parent <= oend))
{
j=(unsigned int)( nai[i].parent-oai );
nai[i].parent= &(nai[j]);
}
if ((nai[i].next >= oai) &&
(nai[i].next <= oend))
{
j=(unsigned int)( nai[i].next-oai );
nai[i].next= &(nai[j]);
}
if ((nai[i].down >= oai) &&
(nai[i].down <= oend))
{
j=(unsigned int)( nai[i].down-oai );
nai[i].down= &(nai[j]);
}
}
}
sk->max=num;
sk->items=nai;
return(0);
}
return(BER_ERR_OUT_OF_ITEMS_STORAGE);
}
#endif /* SPLIT_BER_ITEMS_SK_GROW */
#ifdef SPLIT_BER_ITEMS_SK_FREE
void BER_ITEMS_SK_free(sk)
BER_ITEMS_SK *sk;
{
unsigned int i;
for (i=0; i<sk->max; i++)
{
if ((sk->items[i].item.data.bytes != NULL) &&
(sk->items[i].item.flags & BER_FLAG_DYNAMIC))
{
Free(sk->items[i].item.data.bytes);
sk->items[i].item.data.bytes=NULL;
}
}
if ((sk->flags & BER_FLAG_DYNAMIC_ITEMS) && (sk->items != NULL))
{
Free(sk->items);
sk->items=NULL;
}
sk->num=0;
if (sk->flags & BER_FLAG_DYNAMIC)
Free(sk);
}
#endif /* SPLIT_BER_ITEMS_SK_FREE */
#endif /* !(defined(NO_SPLIT) && defined(SPLIT_FILE)) */

View File

@ -0,0 +1,437 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - tools - makerom.TWL
File: ber_lib.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/* $Id$ */
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "ber_lcl.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BER_NUM_BITS
#define SPLIT_BER_ITEM_CMP_BYTES
#define SPLIT_BER_ITEM_CMP_TAG
#define SPLIT_BER_ITEM_INIT
#define SPLIT_BER_ITEMS_INIT
#define SPLIT_BER_ITEM_SET_ALL
#define SPLIT_BER_ITEM_SET_HEADER
#define SPLIT_BER_ITEM_SET_PREFIX_BYTE
#define SPLIT_BER_ITEM_SET_DATA
#define SPLIT_BER_READ_ITEM
#endif /* NO_SPLIT */
#ifdef SPLIT_BER_NUM_BITS
/**
* Calculates the number of used bits in a buffer bytes. This function is
* useful when dealing with a BER item that is a bit string.
*
* @param buf [In] The buffer of data.
* @param len [In] The length of the buffer in bytes.
* @param bigendian [In] Indicates that the bits in the data is order in
* big endian order.
*
* @return The number of bits.
*/
int R_num_bits(unsigned char *buf, int len, int bigendian)
{
int ret;
int i;
int j;
int inc;
int c;
if (len == 0)
{
return(0);
}
if (bigendian)
{
inc = 1;
j = 0;
}
else
{
j = len - 1;
inc = -1;
}
ret = (len-1)*8;
for (i = 0; i < len; i++)
{
c = buf[j];
if (c == 0)
{
ret -= 8;
j += inc;
}
else
{
if (c & 0x80)
{
return(ret+8);
}
if (c & 0x40)
{
return(ret+7);
}
if (c & 0x20)
{
return(ret+6);
}
if (c & 0x10)
{
return(ret+5);
}
if (c & 0x08)
{
return(ret+4);
}
if (c & 0x04)
{
return(ret+3);
}
if (c & 0x02)
{
return(ret+2);
}
/* if (c & 0x01) */
{
return(ret+1);
}
}
}
return(0);
}
#endif /* SPLIT_BER_NUM_BITS */
#ifdef SPLIT_BER_ITEM_CMP_BYTES
/**
* Compares the data bytes of the BER item with the data of the buffer.
*
* @param a [In] A BER item.
* @param d [In] A buffer of data.
* @param l [In] The length of the data.
*
* @return Indication of a match:<br>
* <li>0 indicates a match</li>
* <li>BER_ERR_CMP_BYTES indicates no match</li>
*/
int BER_ITEM_cmp_bytes(BER_ITEM *a, unsigned char *d, unsigned int l)
{
unsigned char *b;
if (l != a->data.len)
{
return(BER_ERR_CMP_BYTES);
}
if (l == 0)
{
return(0);
}
b = a->data.bytes;
if (BER_prefix_byte(a))
{
if (a->prefix_byte != *(d++))
{
return(BER_ERR_CMP_BYTES);
}
l--;
}
if (Memcmp(d,b,l) != 0)
{
return(BER_ERR_CMP_BYTES);
}
return(0);
}
#endif /* SPLIT_BER_ITEM_CMP_BYTES */
#ifdef SPLIT_BER_ITEM_CMP_TAG
/**
* Compares the tag of a BER item with a BER type value for a match.
*
* @param a [In] A BER item.
* @param type [In] A type of BER item.
*
* @return Indication of a match:<br>
* <li>0 indicares a match</li>
* <li>BER_ERR_CMP_TAG indicates no match</li>
*/
int BER_ITEM_cmp_tag(BER_ITEM *a, unsigned int type)
{
int i;
int j;
if (a->type != type)
{
return(BER_ERR_CMP_TAG);
}
if ((a->info & BER_PRIVATE) != 0)
{
return(BER_ERR_CMP_TAG);
}
i = ((a->type == BER_SEQUENCE) || (a->type == BER_SET));
j = (a->info&BER_CONSTRUCTED) ? 1 : 0;
return((i == j) ? 0: BER_ERR_CMP_TAG);
}
#endif /* SPLIT_BER_ITEM_CMP_TAG */
#ifdef SPLIT_BER_ITEM_INIT
/**
* Initializes a BER item.
*
* @param item [In] A BER item.
*
* @pre The BER item is not a NULL pointer.
*/
void BER_ITEM_init(BER_ITEM *item)
{
Memset(item, 0, sizeof(BER_ITEM));
}
#endif /* SPLIT_BER_ITEM_INIT */
#ifdef SPLIT_BER_ITEMS_INIT
/**
* Initializes a BER items.
*
* @param items [In] A BER items.
*
* @pre The BER item is not a NULL pointer.
*/
void BER_ITEMS_init(BER_ITEMS *items)
{
Memset(items, 0, sizeof(BER_ITEMS));
}
#endif /* SPLIT_BER_ITEMS_INIT */
#ifdef SPLIT_BER_ITEM_SET_ALL
/**
* Sets the data against a BER item.
*
* @param item [In] A BER item.
* @param sclass [In] The class of a BER item.
* @param tag [In] The tag of a BER item.
* @param data [In] The data of a BER item.
* @param len [In] The length of the data of a BER item.
* @param info [In] The info of a BER item.
* @param flags [In] The flags of a BER item.
*/
void BER_ITEM_set_all(BER_ITEM *item, unsigned int sclass, unsigned int tag,
unsigned char *data, unsigned int len, unsigned int info,
unsigned int flags)
{
BER_ITEM_set_header(item, sclass, tag, info);
BER_ITEM_set_data(item, data, len);
item->flags |= flags;
}
#endif /* SPLIT_BER_ITEM_SET_ALL */
#ifdef SPLIT_BER_ITEM_SET_HEADER
/**
* Sets the header data against a BER item.
*
* @param item [In] A BER item.
* @param sclass [In] The class of a BER item.
* @param tag [In] The tag of a BER item.
* @param info [In] The info of a BER item.
*/
void BER_ITEM_set_header(BER_ITEM *item, unsigned int sclass, unsigned int tag,
unsigned int info)
{
item->info = (unsigned char)( (sclass & BER_PRIVATE) |
(info & (BER_INFO_MASK | BER_CONSTRUCTED)) );
item->flags |= BER_FLAG_INVALID_LENGTH;
if (((sclass & BER_PRIVATE) == 0) &&
((tag == BER_SEQUENCE) || (tag == BER_SET)))
{
item->info |= BER_CONSTRUCTED;
}
item->type = tag;
}
#endif /* SPLIT_BER_ITEM_SET_HEADER */
#ifdef SPLIT_BER_ITEM_SET_PREFIX_BYTE
/**
* Places a byte at the front of the data of a BER item. This is useful for
* handling bit strings that require a bytes to be placed before the actual
* data.
*
* @param item [In] A BER item.
* @param abyte [In] A byte.
*/
void BER_ITEM_set_prefix_byte(BER_ITEM *item, unsigned int abyte)
{
if ((item->flags & BER_FLAG_PREFIX_BYTE) == 0)
{
item->flags |= BER_FLAG_PREFIX_BYTE;
item->data.len++;
}
item->prefix_byte = (unsigned char)( abyte & 0xff );
}
#endif /* SPLIT_BER_ITEM_SET_PREFIX_BYTE */
#ifdef SPLIT_BER_ITEM_SET_DATA
/**
* Sets data against a BER item.
*
* @param item [In] A BER item.
* @param data [In] The data of a BER item.
* @param len [In] The length of the data of a BER item.
*/
void BER_ITEM_set_data(BER_ITEM *item, unsigned char *data, unsigned int len)
{
item->flags |= BER_FLAG_INVALID_LENGTH;
item->data.bytes = data;
item->data.len = len;
}
#endif /* SPLIT_BER_ITEM_SET_DATA */
#ifdef SPLIT_BER_READ_ITEM
/**
* Reads the data from the buffer as a BER item and stores the header
* information into <i>item</i>.
*
* @param item [In] A BER item.
* @param p [In] A buffer of data.
* @param max [In] The number of bytes in buffer.
*/
int BER_read_item(BER_ITEM *item, unsigned char *p, unsigned long max)
{
unsigned int i=0;
unsigned int tag;
unsigned int j;
unsigned int x;
unsigned int tclass;
unsigned long len;
if (2 > max)
{
return(BER_ERR_NOT_ENOUGH_BYTES);
}
tclass = p[i++];
/* First get the class and constructed flags */
item->info = (unsigned char)( tclass & (BER_PRIVATE | BER_CONSTRUCTED) );
/* Get the tag */
tag = tclass & BER_PRIMITIVE_TAG_MASK;
if (tag == BER_PRIMITIVE_TAG_MASK)
{
/* This code handles tags greater than 30 */
tag = 0;
j =0;
for (;;)
{
if ((unsigned long)i >= max)
{
return(BER_ERR_NOT_ENOUGH_BYTES);
}
x = p[i++];
tag |= x & 0x7f;
if (x & 0x80)
{
break;
}
j += 7;
if (j > BER_MAX_TAG_LEN_IN_BITS)
{
return(BER_ERR_TAG_TOO_LONG);
}
tag<<=7;
}
}
item->type = tag;
/* Now get the length */
if ((unsigned long)i >= max)
{
return(BER_ERR_NOT_ENOUGH_BYTES);
}
len = p[i++];
if (len & 0x80)
{ /* Long or extended */
len &= 0x7f;
if (len == 0)
{
item->info |= BER_ILEN;
/* Don't set this flag if indefinite length encoding.
* Assume if the Constructed bit is set that it is indef encoding.
*/
if (!(tclass & BER_CONSTRUCTED))
item->flags |= BER_FLAG_INVALID_LENGTH;
}
else
{
if (len > sizeof(unsigned long))
{
return(BER_ERR_LENGTH_TOO_LARGE);
}
if ((unsigned long)i+len >= max)
{
return(BER_ERR_NOT_ENOUGH_BYTES);
}
j = len;
len = 0;
for (;;)
{
len |= p[i++];
if (--j <= 0)
{
break;
}
len <<= 8;
}
}
}
item->data.len = len;
item->data.bytes = &(p[i]);
item->hlen = (unsigned char)i;
#ifndef NO_STREAM
/* Keep a copy of the header for an outer sequence. */
Memcpy(item->header, p, i);
#endif /* !NO_STREAM */
return(BER_OK);
}
#endif /* SPLIT_BER_READ_ITEM */
#endif /* !(defined(NO_SPLIT) && defined(SPLIT_FILE)) */

View File

@ -0,0 +1,251 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - tools - makerom.TWL
File: ber_par.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/* $Id$ */
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "ber_lcl.h"
/* We need to 'parse' the input data into an BER_ITEMS_SK, which is composed of
* BER_ITEMS.
* For definite length encoding, we read a full 'level' at a time, and then
* process the sub-elements.
* For indefinite encoding, we go as 'deep' as we can, updating the
* length info of the indefinite encodings as we go.
* This is easy to do because when we go back up to our parent,
* just compare it's start data byte with the current pointer.
*/
#define READ_NEXT_ITEM 1
#define GO_UP 2
int BER_parse(BER_ITEMS_SK *sk, unsigned char *ino, unsigned long m_len,
unsigned long *n_used)
{
int this_idx;
int next_idx;
BER_ITEMS *this = NULL;
BER_ITEMS *next = NULL;
int ret=999;
int state;
unsigned char *in = ino;
unsigned char *max = in + m_len;
unsigned char *end = max;
int inf = 0;
int pinf = 0;
int con = 0;
int down;
state = READ_NEXT_ITEM;
down = 1;
this_idx = -1;
pinf = 0;
for (;;)
{
switch (state)
{
case READ_NEXT_ITEM:
/* Read the item into 'next' */
if ((ret=BER_ITEMS_SK_get(sk,&next_idx)) != 0)
{
goto err;
}
next=BER_ITEMS_SK_items(sk,next_idx);
ret = BER_read_item(&(next->item), in, (unsigned long)(end - in));
if (ret != 0)
{
goto err;
}
/* Check the length of the data against what is available */
if (next->item.data.len > (unsigned long)(end - in))
{
ret = BER_ERR_NOT_ENOUGH_BYTES;
goto err;
}
inf = BER_indefinite_encoding(&(next->item));
con = BER_constructed(&(next->item));
in += next->item.hlen;
if (this_idx == -1)
{
this = NULL;
}
else
{
this = BER_ITEMS_SK_items(sk, this_idx);
}
/* If we are pushing it under, do so */
if (down)
{
next->parent = this;
if (this != NULL)
{
this->down = next;
if (!pinf)
{
end = this->item.data.bytes+ this->item.data.len;
}
pinf = BER_indefinite_encoding(&this->item);
}
else
{
pinf = 0;
}
next->next = NULL;
}
else
{
next->parent = this->parent;
next->next = NULL;
this->next = next;
}
#ifndef NO_STREAM
next->item.seen = next->item.data.len;
next->item.part_len = next->item.data.len;
#endif /* !NO_STREAM */
down = 0;
this = next;
this_idx = next_idx;
if ((this->item.type == BER_EOC) && (this->item.data.len == 0) &&
(BER_class(&(this->item)) == BER_UNIVERSAL))
{
if (pinf)
{
this->parent->item.data.len=(unsigned long)
(in - this->parent->item.data.bytes);
#ifndef NO_STREAM
this->parent->item.seen = this->parent->item.data.len;
this->parent->item.part_len = this->parent->item.data.len;
#endif /* !NO_STREAM */
state = GO_UP;
break;
}
else
{
ret = BER_ERR_UNEXPECTED_EOC;
goto err;
}
}
if (con && (inf || (this->item.data.len > 0)))
{
pinf = inf;
down = 1;
}
else
{
in += this->item.data.len;
}
if (in > end)
{
ret = BER_ERR_NOT_ENOUGH_BYTES;
goto err;
}
if (in == end)
{
state = GO_UP;
}
else
{
state = READ_NEXT_ITEM;
}
if (inf && !con)
{
ret = BER_ERR_INVALID_LENGTH_ENCODING;
goto err;
}
break;
case GO_UP:
/* this is valid and is the 'end'. We need to
* go back up one and then see if we contiune or
* go_up again. */
this_idx +=(int)(this->parent-this);
this = this->parent;
down = 0;
if (this == NULL)
{
ret = 0;
goto end; /* we have finished */
}
/* Must have finished this one */
/* inf = BER_indefinite_encoding(&this->item); */
if (this->parent != NULL)
{
pinf = BER_indefinite_encoding(&this->parent->item);
if (pinf)
{
end = max;
}
else
{
end = this->parent->item.data.bytes +
this->parent->item.data.len;
}
}
else
{
if (BER_indefinite_encoding(&this->item))
{
ret = 0;
goto end;
}
pinf = 0;
end = max;
}
if (end < in)
{
ret = BER_ERR_NOT_ENOUGH_BYTES;
goto err;
}
if (end == in)
{
state = GO_UP;
}
else
{
state = READ_NEXT_ITEM;
}
break;
default:
break;
}
}
end:
/* if there were no errors we set the length of data we consumed
* if the user wants to know that information.
*/
if (n_used != NULL)
*n_used = (unsigned long)( in - ino );
err:
return(ret);
}