mirror of
https://github.com/rvtr/ctr_eFuse.git
synced 2025-11-02 00:11:04 -04:00
ソースコードの分割。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_eFuse@16 ff987cc8-cf2f-4642-8568-d52cce064691
This commit is contained in:
parent
928ab41882
commit
d323c591cd
3
Makefile
3
Makefile
@ -71,7 +71,8 @@ TARGET = gen_id
|
||||
|
||||
KEYS_C = cr_gen_id_rsa_key_priv.c cr_gen_id_rsa_key_pub.c
|
||||
KEYS_H = $(KEYS_C:.c=.h)
|
||||
SRCS = main.c cr_generate_id.c cr_enc_id.c cr_alloc.c cr_hsm_code.c $(KEYS_C)
|
||||
SRCS = main.c cr_generate_id.c cr_hsm_util.c cr_keyPair.c \
|
||||
cr_deviceCert.c cr_enc_id.c cr_alloc.c cr_hsm_code.c $(KEYS_C)
|
||||
|
||||
ifeq ($(USE_SFMT),TRUE)
|
||||
SRCS += $(SFMT_DIR)/SFMT.c
|
||||
|
||||
248
cr_deviceCert.c
Normal file
248
cr_deviceCert.c
Normal file
@ -0,0 +1,248 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_HSM
|
||||
// nShield
|
||||
#include "nfastapp.h"
|
||||
#include "nfkm.h"
|
||||
#include "rqcard-applic.h"
|
||||
#include "rqcard-fips.h"
|
||||
// nShield optional
|
||||
#include "simplebignum.h"
|
||||
#endif // USE_HSM
|
||||
|
||||
// openssl
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/aes.h>
|
||||
|
||||
#include "ec_lcl.h" // ec_key_st構造体の参照に必要
|
||||
|
||||
|
||||
#include "cr_generate_id.h"
|
||||
#include "cr_generate_id_private.h"
|
||||
#include "cr_alloc.h"
|
||||
|
||||
#define CR_CERT_EXPIRE_SECS ( 60*60*24*365* 20 ) // デバイス証明書期限=20年
|
||||
|
||||
#define CA_FILE "dummyCA/NintendoCTR2_dummy.crt"
|
||||
#define CA_KEY "dummyCA/NintendoCTR2_priv_dummy.pem"
|
||||
|
||||
const char *issuerNameDev = "NintendoCA - G2_NintendoCTR2dev";
|
||||
const char *issuerNameProd = "NintendoCA - G2_NintendoCTR2prod";
|
||||
|
||||
// TWL device cert base
|
||||
typedef struct CTR_Device_Cert
|
||||
{
|
||||
u8 sigType[ 4 ]; // 0x000 - 0x003 : 0x00010002, signature type is ECDSA
|
||||
u8 eccSignature[ 60 ]; // 0x004 - 0x03F : ECDSA using SHA-1 and CA key
|
||||
u8 padding0[ 64 ]; // 0x040 - 0x07F : zero-filled
|
||||
u8 issuerName[ 64 ]; // 0x080 - 0x0BF : issuer name, "Root-CA00000002-MS00000008"
|
||||
u8 keyType[ 4 ]; // 0x0C0 - 0x0C3 : 0x00000002, cert public key type is ECC233
|
||||
u8 subject[ 64 ]; // 0x0C4 - 0x103 : subject field, "CTxxxxxxxx-yyyyyyyyyyyyyyyy"
|
||||
u32 expiryDate; // 0x104 - 0x107 : second from Epoch (Jan 1, 1970 00:00)
|
||||
u8 eccPubKey[ 60 ]; // 0x108 - 0x143 : cert public key (openssl sect233r1)
|
||||
u8 padding1[ 60 ]; // 0x144 - 0x17F : zero-filled
|
||||
} CTR_Device_Cert;
|
||||
|
||||
|
||||
|
||||
// create CTR Custom cert
|
||||
static int generate_CTRCustom_cert( CTR_Device_Cert *cert, u32 deviceId, u8 bondingOption, u32 timestamp )
|
||||
{
|
||||
int result = 0;
|
||||
char str[80];
|
||||
|
||||
if ( sizeof( CTR_Device_Cert ) > 384 )
|
||||
{
|
||||
//ret_code = CR_GENID_ERROR_CERT_BUF_SIZE; // ATODE
|
||||
return 255;
|
||||
}
|
||||
|
||||
// sigType
|
||||
cert->sigType[0] = 0x00;
|
||||
cert->sigType[1] = 0x01;
|
||||
cert->sigType[2] = 0x00;
|
||||
cert->sigType[3] = 0x02;
|
||||
|
||||
// issuerName
|
||||
memcpy( cert->issuerName, issuerNameDev, strlen( issuerNameDev ) );
|
||||
|
||||
// keyType
|
||||
cert->keyType[0] = 0x00;
|
||||
cert->keyType[1] = 0x00;
|
||||
cert->keyType[2] = 0x00;
|
||||
cert->keyType[3] = 0x01;
|
||||
|
||||
// subject : CT + deviceID + BondingOption
|
||||
sprintf( str, "CT%08X%02X", (unsigned int)deviceId, bondingOption );
|
||||
memcpy( cert->subject, str, strlen( str ) );
|
||||
|
||||
// expiryDate
|
||||
#ifdef USE_HSM
|
||||
result = hsm_get_rtc( &cert->expiryDate );
|
||||
if ( result != 0 )
|
||||
{
|
||||
printf( "error(%d) : hsm_get_rtc\n", result );
|
||||
return result;
|
||||
}
|
||||
#else // !USE_HSM
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
gettimeofday(&tv,&tz);
|
||||
cert->expiryDate = tv.tv_sec;
|
||||
}
|
||||
#endif // USE_HSM
|
||||
|
||||
#if 0
|
||||
if ( cr_print_flag )
|
||||
{
|
||||
int i;
|
||||
printf( "CTR custom cert\n" );
|
||||
printf( "sigType : 0x%08X\n", *(unsigned int*)cert->sigType );
|
||||
DEBUG_PRINT_ARRAY( "eccSignature:", (const char *)cert->eccSignature, sizeof(cert->eccSignature) );
|
||||
DEBUG_PRINT_ARRAY( "padding0:", (const char *)cert->padding0, sizeof(cert->padding0) );
|
||||
printf( "issuerName : " );
|
||||
for ( i = 0; i < sizeof(cert->issuerName); i++ ) printf( "%c", cert->issuerName[i] );
|
||||
printf( "\n" );
|
||||
printf( "keyType : 0x%08X\n", *(unsigned int*)cert->keyType );
|
||||
printf( "subject : " );
|
||||
for ( i = 0; i < sizeof(cert->subject); i++ ) printf( "%c", cert->subject[i] );
|
||||
printf( "\n" );
|
||||
printf( "expiryDate : 0x%08X\n", (unsigned int)cert->expiryDate );
|
||||
DEBUG_PRINT_ARRAY( "eccPubKey :", (const char *)cert->eccPubKey, sizeof(cert->eccPubKey) );
|
||||
DEBUG_PRINT_ARRAY( "padding1:", (const char *)cert->padding1, sizeof(cert->padding1) );
|
||||
|
||||
// 証明書の書き込みテスト
|
||||
FILE *fp;
|
||||
char fn[256];
|
||||
sprintf( fn, "output/0x%08x.crt", (unsigned int)deviceId );
|
||||
fp = fopen( fn, "w" );
|
||||
fwrite( cert, sizeof( CTR_Device_Cert ), 1, fp );
|
||||
fclose( fp );
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
} // generate_CTRCustom_cert
|
||||
|
||||
24
cr_enc_id.c
24
cr_enc_id.c
@ -119,20 +119,9 @@
|
||||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_HSM
|
||||
// nShield
|
||||
#include "nfastapp.h"
|
||||
#include "nfkm.h"
|
||||
#include "rqcard-applic.h"
|
||||
#include "rqcard-fips.h"
|
||||
// nShield optional
|
||||
#include "simplebignum.h"
|
||||
|
||||
#else // !USE_HSM
|
||||
#ifndef USE_HSM
|
||||
// openssl
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/aes.h>
|
||||
#include "cr_gen_id_rsa_key_priv.h"
|
||||
@ -146,6 +135,17 @@ static unsigned char local_buf_1[CR_ID_BUF_SIZE];
|
||||
static unsigned char local_buf_2[CR_ID_BUF_SIZE];
|
||||
|
||||
|
||||
// ビルドスイッチに応じて、IDバッファをAES/RSAで暗号化
|
||||
int EncryptID( unsigned char *dst_buf, unsigned char *org_buf )
|
||||
{
|
||||
#ifdef ENCRYPT_AES
|
||||
return crypto_aes_enc_dec( dst_buf, org_buf ); // AES
|
||||
#else // !ENCRYPT_AES
|
||||
return crypto_rsa_enc_dec( dst_buf, org_buf ); // RSA pubKey enc
|
||||
#endif // ENCRYPT_AES
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENCRYPT_AES
|
||||
// AES暗号化 -> 復号化 -> ベリファイ
|
||||
|
||||
|
||||
749
cr_generate_id.c
749
cr_generate_id.c
@ -120,531 +120,42 @@
|
||||
#ifdef USE_HSM
|
||||
#include "cr_hsm_code.h"
|
||||
#endif // USE_HSM
|
||||
|
||||
// openssl
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "ec_lcl.h" // ec_key_st構造体の参照に必要
|
||||
#include "openssl-0.9.8k/crypto/pem/pem.h" // for PEM_read_X509 関数
|
||||
|
||||
|
||||
#include "cr_generate_id.h"
|
||||
#include "cr_generate_id_private.h"
|
||||
#include "cr_alloc.h"
|
||||
|
||||
#define CR_GEN_ID_VERSION 1
|
||||
#define CR_NUM_OF_SERIAL 5
|
||||
#define CR_RSV_LENGTH 0x0C
|
||||
#define CR_RANDOM_LENGTH 0x50
|
||||
#define EC_PRIVATE_KEY_LENGTH 0x20
|
||||
#define ECDSA_SIGN_LENGTH 0x44
|
||||
#define EC_CURVE_NAME NID_sect233r1
|
||||
|
||||
#define CA_FILE "dummyCA/NintendoCTR2_dummy.crt"
|
||||
#define CA_KEY "dummyCA/NintendoCTR2_priv_dummy.pem"
|
||||
#define DAYS_TILL_EXPIRE (365*10)
|
||||
#define EXPIRE_SECS (60*60*24*DAYS_TILL_EXPIRE)
|
||||
|
||||
#define AES_PASS_PHRASE "foo1foo2foo3foo4" // TORIAEZU
|
||||
|
||||
#define HSM_MODULE_ID 1
|
||||
|
||||
const char *issuerNameDev = "NintendoCA - G2_NintendoCTR2dev";
|
||||
const char *issuerNameProd = "NintendoCA - G2_NintendoCTR2prod";
|
||||
|
||||
static struct _caInfo
|
||||
{
|
||||
X509 *cert; // 証明書
|
||||
EVP_PKEY *privKey; // 秘密鍵
|
||||
}
|
||||
caInfo;
|
||||
|
||||
typedef struct _certEntry
|
||||
{
|
||||
char *key;
|
||||
char *value;
|
||||
}
|
||||
certEntry;
|
||||
|
||||
#define ENTRY_COUNT 6
|
||||
certEntry certEntries[ENTRY_COUNT] =
|
||||
{
|
||||
{ "countryName", "JP" },
|
||||
{ "stateOrProvinceName", "KYOTO" },
|
||||
{ "localityName", "KYOTO" },
|
||||
{ "organizationName", "NINTENDO" },
|
||||
{ "organizationalUnitName", "CTR" },
|
||||
{ "commonName", "Device" }
|
||||
};
|
||||
|
||||
// TWL device cert base
|
||||
typedef struct CTR_Device_Cert
|
||||
{
|
||||
u8 sigType[ 4 ]; // 0x000 - 0x003 : 0x00010002, signature type is ECDSA
|
||||
u8 eccSignature[ 60 ]; // 0x004 - 0x03F : ECDSA using SHA-1 and CA key
|
||||
u8 padding0[ 64 ]; // 0x040 - 0x07F : zero-filled
|
||||
u8 issuerName[ 64 ]; // 0x080 - 0x0BF : issuer name, "Root-CA00000002-MS00000008"
|
||||
u8 keyType[ 4 ]; // 0x0C0 - 0x0C3 : 0x00000002, cert public key type is ECC233
|
||||
u8 subject[ 64 ]; // 0x0C4 - 0x103 : subject field, "CTxxxxxxxx-yyyyyyyyyyyyyyyy"
|
||||
u32 expiryDate; // 0x104 - 0x107 : second from Epoch (Jan 1, 1970 00:00)
|
||||
u8 eccPubKey[ 60 ]; // 0x108 - 0x143 : cert public key (openssl sect233r1)
|
||||
u8 padding1[ 60 ]; // 0x144 - 0x17F : zero-filled
|
||||
} CTR_Device_Cert;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u32 magic_number; /* 0x00 - 0x03 = 0xdeadb00f 確定!*/
|
||||
u32 serial[CR_NUM_OF_SERIAL]; /* 0x04 - 0x07 32bit device ID
|
||||
(32bit。1固定カウントアップ。)
|
||||
(本ID+randomの先頭0x1C bytesを組み合わせて、デバイス秘密鍵とする。)
|
||||
0x08 - 0x0F 64bit CTR番号 seed
|
||||
(34bitのみ使用。1~4の乱数カウントアップ)
|
||||
0x10 - 0x17 64bit 予備ID
|
||||
(64bitフルに使用。1~0x100000000の乱数カウントアップ)
|
||||
*/
|
||||
u8 version; /* 0x18 = CR_GEN_ID_VERSION = 1 */
|
||||
u8 bondingOption; /* 0x19 ボンディングオプション */
|
||||
u8 year; /* 0x1A デバイス証明書発行時間 (HSMから取得) */
|
||||
u8 month; /* 0x1B */
|
||||
u8 mday; /* 0x1C */
|
||||
u8 hour; /* 0x1D */
|
||||
u8 min; /* 0x1E */
|
||||
u8 sec; /* 0x1F */
|
||||
u8 devicePrivKey[ EC_PRIVATE_KEY_LENGTH ];
|
||||
/* 0x20 - 0x3F ECC233 private key (big endian) ユニーク性保証なし */
|
||||
u8 deviceCertSign[ ECDSA_SIGN_LENGTH ];
|
||||
/* 0x40 - 0x83 ECC233 ECDSA signature (big endian) */
|
||||
u8 reserved[ CR_RSV_LENGTH ]; /* 0x84 - 0x8F 予約 */
|
||||
u8 random[ CR_RANDOM_LENGTH ]; /* 0x90 - 0xDF 乱数 */
|
||||
u8 hash[ SHA256_DIGEST_LENGTH ]; /* 0xE0 - 0xFF "0x00-0xDF"領域のSHA256ハッシュ */
|
||||
} CR_ID_BUFFER; /* 合計256bytes = 2048bit */
|
||||
u32 magic_number; /* 0x00 - 0x03 0x01234567 確定!*/
|
||||
u32 serial0; /* 0x04 - 0x07 */
|
||||
u32 openssl_err_code; /* 0x08 - 0x0b */
|
||||
s32 top; /* 0x0c - 0x0f */
|
||||
s32 bottom; /* 0x10 - 0x13 */
|
||||
|
||||
typedef struct {
|
||||
u32 magic_number; /* 0x00 - 0x03 0x01234567 確定!*/
|
||||
u32 serial0; /* 0x04 - 0x07 */
|
||||
u32 openssl_err_code; /* 0x08 - 0x0b */
|
||||
s32 top; /* 0x0c - 0x0f */
|
||||
s32 bottom; /* 0x10 - 0x13 */
|
||||
|
||||
/* #define ERR_NUM_ERRORS 16 */
|
||||
u32 err_buffer[ERR_NUM_ERRORS]; /* 0x14 - 0x17 .... 0x50 - 0x53 */
|
||||
//#define ERR_GET_LIB(l) (int)((((unsigned long)l)>>24L)&0xffL)
|
||||
//#define ERR_GET_FUNC(l) (int)((((unsigned long)l)>>12L)&0xfffL)
|
||||
//#define ERR_GET_REASON(l) (int)((l)&0xfffL)
|
||||
//#define ERR_FATAL_ERROR(l) (int)((l)&ERR_R_FATAL)
|
||||
s32 err_line[ERR_NUM_ERRORS]; /* 0x54 - 0x57 .... 0x90 - 0x93 */
|
||||
/* #define ERR_NUM_ERRORS 16 */
|
||||
u32 err_buffer[ERR_NUM_ERRORS]; /* 0x14 - 0x17 .... 0x50 - 0x53 */
|
||||
//#define ERR_GET_LIB(l) (int)((((unsigned long)l)>>24L)&0xffL)
|
||||
//#define ERR_GET_FUNC(l) (int)((((unsigned long)l)>>12L)&0xfffL)
|
||||
//#define ERR_GET_REASON(l) (int)((l)&0xfffL)
|
||||
//#define ERR_FATAL_ERROR(l) (int)((l)&ERR_R_FATAL)
|
||||
s32 err_line[ERR_NUM_ERRORS]; /* 0x54 - 0x57 .... 0x90 - 0x93 */
|
||||
} CR_ERR_BUFFER;
|
||||
|
||||
|
||||
int cr_print_flag = 0;
|
||||
|
||||
// EC秘密鍵を生成
|
||||
static int generate_EC_private_key( EC_KEY *eckey, u8 *privKey )
|
||||
{
|
||||
int ret_code = 0;
|
||||
BIGNUM *bn_privkey = NULL;
|
||||
|
||||
#ifdef USE_HSM
|
||||
ret_code = hsm_generate_random( privKey, EC_PRIVATE_KEY_LENGTH );
|
||||
if ( ret_code != CR_GENID_SUCCESS )
|
||||
{
|
||||
printf( "error(%d) : hsm_generate_random\n", ret_code );
|
||||
return ret_code;
|
||||
}
|
||||
#else // !USE_HSM
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < EC_PRIVATE_KEY_LENGTH; i++ )
|
||||
{
|
||||
privKey[i] = (u8)rand();
|
||||
}
|
||||
}
|
||||
#endif // USE_HSM
|
||||
|
||||
// ECC233 で30バイトだけ利用するので、後ろ2バイトは0で埋める
|
||||
// (DER(BER) が big endian なので、ここでは先頭2byte)
|
||||
// + 7bit clear
|
||||
privKey[ 0 ] = 0;
|
||||
privKey[ 1 ] = 0;
|
||||
privKey[ 2 ] &= 0x01;
|
||||
|
||||
// 生成した秘密鍵をBNに変換して、eckeyにセット
|
||||
// ※bn_privkeyは、生成に成功した場合、ここではBN_freeされずにeckey要素の一つになって引き渡されます。
|
||||
bn_privkey = BN_new();
|
||||
if( bn_privkey == NULL )
|
||||
{
|
||||
return CR_GENID_ERROR_BN_NEW_0;
|
||||
}
|
||||
BN_init( bn_privkey ); /* memset(a,0,sizeof(BIGNUM)); */
|
||||
(void)BN_bin2bn( privKey, EC_PRIVATE_KEY_LENGTH, bn_privkey );
|
||||
eckey->priv_key = bn_privkey;
|
||||
|
||||
DEBUG_PRINT_ARRAY( "ec private key:", (const char *)privKey, EC_PRIVATE_KEY_LENGTH );
|
||||
|
||||
return ret_code;
|
||||
} // generate_EC_private_key
|
||||
|
||||
// EC公開鍵を生成
|
||||
static int generate_EC_public_key( EC_KEY *eckey )
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *priv_key = NULL, *order = NULL;
|
||||
EC_POINT *pub_key = NULL;
|
||||
|
||||
if (!eckey || !eckey->group)
|
||||
{
|
||||
ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((order = BN_new()) == NULL) goto err;
|
||||
if ((ctx = BN_CTX_new()) == NULL) goto err;
|
||||
|
||||
if (eckey->priv_key == NULL)
|
||||
{
|
||||
priv_key = BN_new();
|
||||
if (priv_key == NULL) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
priv_key = eckey->priv_key;
|
||||
}
|
||||
|
||||
if (!EC_GROUP_get_order(eckey->group, order, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
#if 0 // 2009.09.25 これが実行されると、秘密鍵が乱数化されてしまい、指定した秘密鍵と変わってしまうためコメントアウトする。
|
||||
do
|
||||
if (!BN_rand_range(priv_key, order))
|
||||
goto err;
|
||||
while (BN_is_zero(priv_key));
|
||||
#endif
|
||||
|
||||
if (eckey->pub_key == NULL)
|
||||
{
|
||||
pub_key = EC_POINT_new(eckey->group);
|
||||
if (pub_key == NULL) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
pub_key = eckey->pub_key;
|
||||
|
||||
if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
eckey->priv_key = priv_key;
|
||||
eckey->pub_key = pub_key;
|
||||
|
||||
ok=1;
|
||||
|
||||
err:
|
||||
if (order)
|
||||
BN_free(order);
|
||||
if (pub_key != NULL && eckey->pub_key == NULL)
|
||||
EC_POINT_free(pub_key);
|
||||
if (priv_key != NULL && eckey->priv_key == NULL)
|
||||
BN_free(priv_key);
|
||||
if (ctx != NULL)
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return(ok);
|
||||
} // generate_EC_public_key
|
||||
|
||||
// X.509 証明書要求を生成
|
||||
static int generate_X509_csr( EVP_PKEY *evp_pkey, X509_REQ *req )
|
||||
{
|
||||
int i = 0;
|
||||
int ok = 0;
|
||||
|
||||
X509_NAME *subj;
|
||||
|
||||
X509_REQ_set_pubkey( req, evp_pkey );
|
||||
|
||||
// subjectName 割り当て
|
||||
subj = X509_NAME_new();
|
||||
if ( !subj )
|
||||
{
|
||||
printf( "error : X509_NAME_new\n" );
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
for ( i = 0; i < ENTRY_COUNT; i++ )
|
||||
{
|
||||
int nid;
|
||||
X509_NAME_ENTRY *ent;
|
||||
|
||||
nid = OBJ_txt2nid( certEntries[i].key );
|
||||
if ( nid == NID_undef )
|
||||
{
|
||||
printf( "Error finding NID for %s\n", certEntries[i].key );
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
ent = X509_NAME_ENTRY_create_by_NID( NULL, nid, MBSTRING_ASC,
|
||||
certEntries[i].value, -1 );
|
||||
if ( !ent )
|
||||
{
|
||||
printf( "error : X509_NAME_ENTRY_create_by_NID\n" );
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
if ( X509_NAME_add_entry( subj, ent, -1, 0 ) != 1 )
|
||||
{
|
||||
printf( "error : X509_NAME_add_entry\n" );
|
||||
return 0; // error
|
||||
}
|
||||
}
|
||||
if ( X509_REQ_set_subject_name( req, subj ) != 1 )
|
||||
{
|
||||
printf( "error : X509_REQ_set_subject_name\n" );
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
// todo : ここで v3 拡張領域をがんばる
|
||||
|
||||
#if 0
|
||||
// EVP_PKEYのタイプがECであるか確認
|
||||
u16 type = EVP_PKEY_type( evp_pkey->type );
|
||||
if ( type != EVP_PKEY_EC )
|
||||
{
|
||||
printf( "error : EVP_PKEY_type, %d\n", type );
|
||||
return 0; // error
|
||||
}
|
||||
#endif
|
||||
|
||||
// 要求に署名する : ECDSA
|
||||
if ( !(X509_REQ_sign( req, evp_pkey, EVP_ecdsa() )) )
|
||||
{
|
||||
printf( "error : X509_REQ_sign\n" );
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
#if 0
|
||||
// CSRの確認
|
||||
if( cr_print_flag )
|
||||
{
|
||||
X509_REQ_print_fp( stdout, req );
|
||||
}
|
||||
#endif
|
||||
|
||||
ok = 1;
|
||||
|
||||
return ( ok );
|
||||
} // generate_X509_csr
|
||||
|
||||
// X.509 証明書を生成
|
||||
static int generate_X509_cert( EVP_PKEY *evp_pkey, X509_REQ *req, X509 *cert, u32 deviceId )
|
||||
{
|
||||
int ok = 0;
|
||||
|
||||
X509_NAME *name;
|
||||
|
||||
#if 1
|
||||
// 要求書に付いている署名の検証を行う
|
||||
EVP_PKEY *pkey;
|
||||
pkey = X509_REQ_get_pubkey( req );
|
||||
if ( !pkey )
|
||||
{
|
||||
printf( "error : X509_REQ_get_pubkey\n" );
|
||||
return 0; // error
|
||||
}
|
||||
if ( X509_REQ_verify( req, pkey ) != 1 )
|
||||
{
|
||||
printf( "error : X509_REQ_verify\n" );
|
||||
return 0; // error
|
||||
}
|
||||
EVP_PKEY_free( pkey );
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// show subjectName
|
||||
name = X509_REQ_get_subject_name( req );
|
||||
if ( !name )
|
||||
{
|
||||
printf( "error : X509_REQ_get_subject_name\n" );
|
||||
return 0; // error
|
||||
}
|
||||
X509_NAME_print_ex_fp( stdout, name, 0, 0 );
|
||||
printf( "\n" );
|
||||
#endif
|
||||
|
||||
// set version = 3 (0x2)
|
||||
if ( X509_set_version( cert, 2L ) != 1 )
|
||||
{
|
||||
printf( "error : X509_set_version\n" );
|
||||
return 0; // error
|
||||
}
|
||||
ASN1_INTEGER_set( X509_get_serialNumber( cert ), deviceId );
|
||||
|
||||
// 証明書の発行者名と所有者名を設定
|
||||
name = X509_REQ_get_subject_name( req );
|
||||
if ( !name )
|
||||
{
|
||||
printf( "error : X509_REQ_get_subject_name\n" );
|
||||
return 0; // error
|
||||
}
|
||||
if ( X509_set_subject_name( cert, name ) != 1 )
|
||||
{
|
||||
printf( "error : X509_set_subject_name\n" );
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
name = X509_get_subject_name( caInfo.cert );
|
||||
if ( !name )
|
||||
{
|
||||
printf( "error : X509_get_subject_name\n" );
|
||||
return 0; // error
|
||||
}
|
||||
if ( X509_set_issuer_name( cert, name ) != 1 )
|
||||
{
|
||||
printf( "error : X509_set_issuer_name\n" );
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
// 証明書に公開鍵を設定する
|
||||
if ( X509_set_pubkey( cert, evp_pkey ) != 1 )
|
||||
{
|
||||
printf( "error : X509_set_pubkey\n" );
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
// 証明書の有効期間を設定する
|
||||
if ( !(X509_gmtime_adj( X509_get_notBefore( cert ), 0 )) )
|
||||
{
|
||||
printf( "error : X509_gmtime_adj before\n" );
|
||||
return 0; // error
|
||||
}
|
||||
if ( !(X509_gmtime_adj( X509_get_notAfter( cert ), EXPIRE_SECS )) )
|
||||
{
|
||||
printf( "error : X509_gmtime_adj after\n" );
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
// CAの秘密鍵を使って証明書に署名する
|
||||
//EVP_MD *dgst = EVP_ecdsa();
|
||||
//printf( "dgst length : %d\n", dgst->md_size );
|
||||
if ( !(X509_sign( cert, caInfo.privKey, EVP_ecdsa() )) )
|
||||
{
|
||||
printf( "error : X509_sign\n" );
|
||||
return 0; // error
|
||||
}
|
||||
|
||||
#if 0
|
||||
// 証明書確認
|
||||
if ( cr_print_flag )
|
||||
{
|
||||
X509_print_fp( stdout, cert );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
DEBUG_PRINT_ARRAY( "eccSignature:", (const char *)cert->signature->data, cert->signature->length );
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// 証明書の書き込みテスト
|
||||
FILE *fp;
|
||||
char fn[256];
|
||||
sprintf( fn, "output/0x%08x.crt", deviceId );
|
||||
fp = fopen( fn, "w" );
|
||||
PEM_write_X509( fp, cert );
|
||||
fclose( fp );
|
||||
#endif
|
||||
|
||||
ok = 1;
|
||||
|
||||
return (ok);
|
||||
} // generate_X509_cert
|
||||
|
||||
// create CTR Custom cert
|
||||
static int generate_CTRCustom_cert( CTR_Device_Cert *cert, u32 deviceId, u8 bondingOption )
|
||||
{
|
||||
int result = 0;
|
||||
char str[80];
|
||||
|
||||
// sigType
|
||||
cert->sigType[0] = 0x00;
|
||||
cert->sigType[1] = 0x01;
|
||||
cert->sigType[2] = 0x00;
|
||||
cert->sigType[3] = 0x02;
|
||||
|
||||
// issuerName
|
||||
memcpy( cert->issuerName, issuerNameDev, strlen( issuerNameDev ) );
|
||||
|
||||
// keyType
|
||||
cert->keyType[0] = 0x00;
|
||||
cert->keyType[1] = 0x00;
|
||||
cert->keyType[2] = 0x00;
|
||||
cert->keyType[3] = 0x01;
|
||||
|
||||
// subject : CT + deviceID + BondingOption
|
||||
sprintf( str, "CT%08X%02X", (unsigned int)deviceId, bondingOption );
|
||||
memcpy( cert->subject, str, strlen( str ) );
|
||||
|
||||
// expiryDate
|
||||
#ifdef USE_HSM
|
||||
result = hsm_get_rtc( &cert->expiryDate );
|
||||
if ( result != 0 )
|
||||
{
|
||||
printf( "error(%d) : hsm_get_rtc\n", result );
|
||||
return result;
|
||||
}
|
||||
#else // !USE_HSM
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
gettimeofday(&tv,&tz);
|
||||
cert->expiryDate = tv.tv_sec;
|
||||
}
|
||||
#endif // USE_HSM
|
||||
|
||||
#if 0
|
||||
if ( cr_print_flag )
|
||||
{
|
||||
int i;
|
||||
printf( "CTR custom cert\n" );
|
||||
printf( "sigType : 0x%08X\n", *(unsigned int*)cert->sigType );
|
||||
DEBUG_PRINT_ARRAY( "eccSignature:", (const char *)cert->eccSignature, sizeof(cert->eccSignature) );
|
||||
DEBUG_PRINT_ARRAY( "padding0:", (const char *)cert->padding0, sizeof(cert->padding0) );
|
||||
printf( "issuerName : " );
|
||||
for ( i = 0; i < sizeof(cert->issuerName); i++ ) printf( "%c", cert->issuerName[i] );
|
||||
printf( "\n" );
|
||||
printf( "keyType : 0x%08X\n", *(unsigned int*)cert->keyType );
|
||||
printf( "subject : " );
|
||||
for ( i = 0; i < sizeof(cert->subject); i++ ) printf( "%c", cert->subject[i] );
|
||||
printf( "\n" );
|
||||
printf( "expiryDate : 0x%08X\n", (unsigned int)cert->expiryDate );
|
||||
DEBUG_PRINT_ARRAY( "eccPubKey :", (const char *)cert->eccPubKey, sizeof(cert->eccPubKey) );
|
||||
DEBUG_PRINT_ARRAY( "padding1:", (const char *)cert->padding1, sizeof(cert->padding1) );
|
||||
|
||||
// 証明書の書き込みテスト
|
||||
FILE *fp;
|
||||
char fn[256];
|
||||
sprintf( fn, "output/0x%08x.crt", (unsigned int)deviceId );
|
||||
fp = fopen( fn, "w" );
|
||||
fwrite( cert, sizeof( CTR_Device_Cert ), 1, fp );
|
||||
fclose( fp );
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
} // generate_CTRCustom_cert
|
||||
|
||||
int cr_generate_id_initialize( void )
|
||||
{
|
||||
int ret_code = 0;
|
||||
FILE *fp;
|
||||
|
||||
|
||||
#ifdef USE_HSM
|
||||
ret_code = hsm_initialize();
|
||||
if ( ret_code != CR_GENID_SUCCESS )
|
||||
@ -654,49 +165,13 @@ int cr_generate_id_initialize( void )
|
||||
}
|
||||
#endif
|
||||
|
||||
// CAの証明書を読み込む
|
||||
fp = fopen( CA_FILE, "r" );
|
||||
if ( !fp )
|
||||
{
|
||||
printf( "error : read CA_Cert file\n" );
|
||||
return 0; // error
|
||||
}
|
||||
caInfo.cert = PEM_read_X509( fp, NULL, NULL, NULL );
|
||||
if ( !(caInfo.cert) )
|
||||
{
|
||||
printf( "error : read CA_Cert in file\n" );
|
||||
return 0; // error
|
||||
}
|
||||
fclose( fp );
|
||||
|
||||
#if 0
|
||||
// CAの証明書確認
|
||||
if ( cr_print_flag )
|
||||
{
|
||||
X509_print_fp( stdout, caCert );
|
||||
}
|
||||
#endif
|
||||
|
||||
// CAの秘密鍵を読み込む
|
||||
fp = fopen( CA_KEY, "r" );
|
||||
if ( !fp )
|
||||
{
|
||||
printf( "error : read CA_KEY file\n" );
|
||||
return 0; // error
|
||||
}
|
||||
caInfo.privKey = PEM_read_PrivateKey( fp, NULL, NULL, NULL );
|
||||
if ( !(caInfo.privKey) )
|
||||
{
|
||||
printf( "error : read CA_KEY in file\n" );
|
||||
return 0; // error
|
||||
}
|
||||
fclose( fp );
|
||||
|
||||
ret_code = 1;
|
||||
|
||||
|
||||
return ( ret_code );
|
||||
} // cr_generate_id_initialize
|
||||
|
||||
|
||||
// generate_id関数のファイナライズ
|
||||
int cr_generate_id_finalize( void )
|
||||
{
|
||||
int ok = 0;
|
||||
@ -721,19 +196,14 @@ int cr_generate_id_finalize( void )
|
||||
エラーが起こったとき id_buf にエラーログを返すか?
|
||||
*/
|
||||
|
||||
|
||||
// generate_id 関数
|
||||
int cr_generate_id( u32 serial[CR_NUM_OF_SERIAL], u8 id_buf[CR_ID_BUF_SIZE], u8 bondingOption )
|
||||
{
|
||||
int i;
|
||||
int ret_code;
|
||||
EC_KEY *my_eckey = NULL;
|
||||
EVP_PKEY *my_evppkey = NULL;
|
||||
|
||||
X509_REQ *req = NULL;
|
||||
X509 *cert = NULL;
|
||||
|
||||
CR_ID_BUFFER *cr_id_buf;
|
||||
u8 hash[SHA256_DIGEST_LENGTH]; /* SHA256 check */
|
||||
CTR_Device_Cert ctr_dev_cert;
|
||||
EC_KEY *my_eckey = NULL;
|
||||
|
||||
if( sizeof(CR_ID_BUFFER) != 256 ) {
|
||||
ret_code = CR_GENID_ERROR_ID_BUF_SIZE;
|
||||
@ -745,12 +215,6 @@ int cr_generate_id( u32 serial[CR_NUM_OF_SERIAL], u8 id_buf[CR_ID_BUF_SIZE], u8
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ( sizeof( CTR_Device_Cert ) > 384 )
|
||||
{
|
||||
//ret_code = CR_GENID_ERROR_CERT_BUF_SIZE; // ATODE
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret_code = CR_GENID_ERROR_NON; /* CR_GENID_ERROR_NON = 0 */
|
||||
|
||||
#if 0
|
||||
@ -792,13 +256,12 @@ int cr_generate_id( u32 serial[CR_NUM_OF_SERIAL], u8 id_buf[CR_ID_BUF_SIZE], u8
|
||||
//--------------------------------------------------------------
|
||||
// 引数のボンディングオプションをセット
|
||||
//--------------------------------------------------------------
|
||||
cr_id_buf->bondingOption = bondingOption;
|
||||
cr_id_buf->bondingOption = bondingOption;
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// serialNo.セット
|
||||
//--------------------------------------------------------------
|
||||
for( i = 0 ; i < CR_NUM_OF_SERIAL ; i++ )
|
||||
{
|
||||
for( i = 0 ; i < CR_NUM_OF_SERIAL ; i++ ) {
|
||||
cr_id_buf->serial[i] = serial[i]; /* serial[0] => ec priv key */
|
||||
}
|
||||
|
||||
@ -809,7 +272,7 @@ int cr_generate_id( u32 serial[CR_NUM_OF_SERIAL], u8 id_buf[CR_ID_BUF_SIZE], u8
|
||||
for( i = 0 ; i < CR_NUM_OF_SERIAL ; i++ ) {
|
||||
if( i == 0 ) printf(" 0x%08x\n", (unsigned int)serial[i] );
|
||||
else if( i & 0x01 ) printf(" 0x%08x", (unsigned int)serial[i] );
|
||||
else printf("%08x\n", (unsigned int)serial[i] );
|
||||
else printf("%08x\n", (unsigned int)serial[i] );
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
@ -818,153 +281,46 @@ int cr_generate_id( u32 serial[CR_NUM_OF_SERIAL], u8 id_buf[CR_ID_BUF_SIZE], u8
|
||||
//--------------------------------------------------------------
|
||||
// タイムスタンプセット
|
||||
//--------------------------------------------------------------
|
||||
{
|
||||
struct tm *tm_time;
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
#ifdef USE_HSM
|
||||
hsm_get_rtc( &tv.tv_sec );
|
||||
#else // !USE_HSM
|
||||
gettimeofday(&tv,&tz);
|
||||
#endif // USE_HSM
|
||||
|
||||
tm_time = gmtime( &tv.tv_sec );
|
||||
|
||||
cr_id_buf->year = (u8)tm_time->tm_year;
|
||||
cr_id_buf->month = (u8)tm_time->tm_mon+1;
|
||||
cr_id_buf->mday = (u8)tm_time->tm_mday;
|
||||
cr_id_buf->hour = (u8)tm_time->tm_hour;
|
||||
cr_id_buf->min = (u8)tm_time->tm_min;
|
||||
cr_id_buf->sec = (u8)tm_time->tm_sec;
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
if( cr_print_flag ) {
|
||||
printf("GMT:%d-%02d-%02d %02d:%02d:%02d\n",
|
||||
tm_time->tm_year+1900, /* 年 */
|
||||
tm_time->tm_mon+1, /* 月 */
|
||||
tm_time->tm_mday, /* 日 */
|
||||
tm_time->tm_hour, /* 時 */
|
||||
tm_time->tm_min, /* 分 */
|
||||
tm_time->tm_sec /* 秒 */
|
||||
);
|
||||
}
|
||||
#endif /* DEBUG_PRINT */
|
||||
ret_code = GetTimestamp( &cr_id_buf->year,
|
||||
&cr_id_buf->month,
|
||||
&cr_id_buf->mday,
|
||||
&cr_id_buf->hour,
|
||||
&cr_id_buf->min,
|
||||
&cr_id_buf->sec,
|
||||
&cr_id_buf->deviceCertExpiryDate );
|
||||
if ( ret_code != 0 ) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// 乱数を生成してセット
|
||||
//--------------------------------------------------------------
|
||||
#ifdef USE_HSM
|
||||
ret_code = hsm_generate_random( cr_id_buf->random, CR_RANDOM_LENGTH );
|
||||
if ( ret_code != CR_GENID_SUCCESS )
|
||||
{
|
||||
printf( "error(%d) : hsm_generate_random\n", ret_code );
|
||||
return ret_code;
|
||||
ret_code = GenerateRandom( cr_id_buf->random, CR_RANDOM_LENGTH );
|
||||
if ( ret_code != CR_GENID_SUCCESS ) {
|
||||
goto end;
|
||||
}
|
||||
#else // !USE_HSM
|
||||
{
|
||||
u16 buffer[ CR_RANDOM_LENGTH / sizeof(u16) ];
|
||||
for( i = 0 ; i < CR_RANDOM_LENGTH / sizeof(u16); i++ ) {
|
||||
buffer[i] = (u16)rand();
|
||||
}
|
||||
memcpy( cr_id_buf->random, buffer, CR_RANDOM_LENGTH );
|
||||
}
|
||||
#endif // USE_HSM
|
||||
|
||||
DEBUG_PRINT_ARRAY( "rand:", (const char *)cr_id_buf->random, CR_RANDOM_LENGTH );
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// 楕円曲線鍵ペアを生成
|
||||
//--------------------------------------------------------------
|
||||
// 楕円を選択 ( NID_X9_62_prime256v1 -> 32bytesまで、 NID_sect571r1 -> 71bytesまで 署名にデータを含められる )
|
||||
my_eckey = EC_KEY_new_by_curve_name( NID_sect233r1 );
|
||||
if( my_eckey == NULL )
|
||||
{
|
||||
ret_code = CR_GENID_ERROR_EC_KEY_NEW_1;
|
||||
ret_code = GenarateECCKeyPair( my_eckey, cr_id_buf->devicePrivKey );
|
||||
if ( ret_code != CR_GENID_SUCCESS ) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 秘密鍵生成
|
||||
ret_code = generate_EC_private_key( my_eckey, cr_id_buf->devicePrivKey );
|
||||
if( ret_code != 0 )
|
||||
{
|
||||
ret_code = CR_GENID_ERROR_EC_GENERATE_PRIVATE_KEY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
// 公開鍵生成
|
||||
ret_code = generate_EC_public_key( my_eckey );
|
||||
if ( ret_code == 0 )
|
||||
{
|
||||
ret_code = CR_GENID_ERROR_EC_GENERATE_PUBLIC_KEY;
|
||||
goto end;
|
||||
}
|
||||
|
||||
// ASN.1 形式指定フラグをセットする
|
||||
// (これをセットしないと色々変なフィールドが入ってしまうため)
|
||||
EC_KEY_set_asn1_flag( my_eckey, 1 );
|
||||
|
||||
ret_code = CR_GENID_ERROR_NON; // TORIAEZU
|
||||
|
||||
#if 0
|
||||
//--------------------------------------------------------------
|
||||
// 生成した鍵ペアをECDSAで動作確認
|
||||
//--------------------------------------------------------------
|
||||
#if 0
|
||||
ret_code = TestECDSA( hoge hoge );
|
||||
// 当然やるべき
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// 証明書の発行に先立ってEVP_PKEYオブジェクトを生成する
|
||||
//--------------------------------------------------------------
|
||||
// EC_KEYを元にEVP_PKEYを生成
|
||||
my_evppkey = EVP_PKEY_new();
|
||||
if ( !my_evppkey )
|
||||
{
|
||||
printf( "error : EVP_PKEY_new\n" );
|
||||
return 0; // error
|
||||
}
|
||||
// assign_EC_KEY だと、鍵オブジェクトを所有するため、メモリリークする?
|
||||
#if 1
|
||||
if ( !EVP_PKEY_set1_EC_KEY( my_evppkey, my_eckey ) )
|
||||
{
|
||||
printf( "error : EVP_PKEY_set1_EC_KEY\n" );
|
||||
return 0; // error
|
||||
}
|
||||
#else
|
||||
if ( !EVP_PKEY_assign_EC_KEY( my_evppkey, my_eckey) )
|
||||
{
|
||||
printf( "error : EVP_PKEY_assign_EC_KEY\n" );
|
||||
return 0; // error
|
||||
}
|
||||
#endif
|
||||
|
||||
//printf( "evp_pkey size : %d\n", EVP_PKEY_size( my_evppkey ) );
|
||||
#if 1
|
||||
//--------------------------------------------------------------
|
||||
// デバイス証明書要求生成
|
||||
//--------------------------------------------------------------
|
||||
req = X509_REQ_new(); // 呼び出し先で new すると正しくメモリ確保されない?
|
||||
if ( !req )
|
||||
{
|
||||
printf( "error : X509_REQ_new\n" );
|
||||
return 0; // error
|
||||
}
|
||||
generate_X509_csr( my_evppkey, req );
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// デバイス証明書発行 (X.509 v3)
|
||||
//--------------------------------------------------------------
|
||||
cert = X509_new(); // 呼び出し先で new すると正しくメモリ確保されない?
|
||||
if ( !cert )
|
||||
{
|
||||
printf( "error : X509_new\n" );
|
||||
return 0; // error
|
||||
}
|
||||
generate_X509_cert( my_evppkey, req, cert, cr_id_buf->serial[0] );
|
||||
//--------------------------------------------------------------
|
||||
// デバイス証明書の署名をセット
|
||||
// デバイス証明書生成&署名+証明書期限セット
|
||||
//--------------------------------------------------------------
|
||||
#if 0
|
||||
int padding = ECDSA_SIGN_LENGTH % cert->signature->length;
|
||||
printf( "padding = %d\n", padding );
|
||||
for ( i = 0; i < padding; i++ )
|
||||
@ -986,7 +342,6 @@ int cr_generate_id( u32 serial[CR_NUM_OF_SERIAL], u8 id_buf[CR_ID_BUF_SIZE], u8
|
||||
len = BN_bn2bin( &my_eckey->pub_key->Y, buf );
|
||||
memcpy( &ctr_dev_cert.eccPubKey[30], buf, len );
|
||||
free( buf );
|
||||
#endif
|
||||
|
||||
// copy sign to Custom cert
|
||||
//#define SHOW_SIG
|
||||
@ -1032,38 +387,32 @@ int cr_generate_id( u32 serial[CR_NUM_OF_SERIAL], u8 id_buf[CR_ID_BUF_SIZE], u8
|
||||
|
||||
#if 0
|
||||
DEBUG_PRINT_ARRAY( "deviceCertSign:", (const char *)cr_id_buf->deviceCertSign, ECDSA_SIGN_LENGTH );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// FuseIDバッファ全体のSHA256ハッシュを算出してセット
|
||||
//--------------------------------------------------------------
|
||||
SHA256(id_buf, CR_ID_BUF_SIZE - SHA256_DIGEST_LENGTH, cr_id_buf->hash);
|
||||
memcpy( hash, cr_id_buf->hash, SHA256_DIGEST_LENGTH );
|
||||
DEBUG_PRINT_ARRAY( "SHA256 Digest:", (const char *)cr_id_buf->hash, SHA256_DIGEST_LENGTH );
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// FuseIDバッファ全体を暗号化
|
||||
// FuseIDバッファ全体をAES or RSAで暗号化
|
||||
//--------------------------------------------------------------
|
||||
DEBUG_PRINT_ARRAY( "ORG buf:", (const char *)id_buf, CR_ID_BUF_SIZE );
|
||||
|
||||
#ifdef ENCRYPT_AES
|
||||
ret_code = crypto_aes_enc_dec( id_buf, id_buf ); // AES
|
||||
#else // !ENCRYPT_AES
|
||||
ret_code = crypto_rsa_enc_dec( id_buf, id_buf ); // RSA pubKey enc
|
||||
#endif // ENCRYPT_AES
|
||||
|
||||
if( ret_code != 0 ) {
|
||||
ret_code = EncryptID( id_buf, id_buf );
|
||||
if( ret_code != CR_GENID_SUCCESS ) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
DEBUG_PRINT_ARRAY( "encrypted:", (const char *)id_buf, CR_ID_BUF_SIZE );
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// 終了処理
|
||||
//--------------------------------------------------------------
|
||||
end:
|
||||
end:
|
||||
/* id_buf[]にエラーログを書き込む。 */
|
||||
if( ret_code != 0 ) {
|
||||
if( ret_code != CR_GENID_SUCCESS ) {
|
||||
ERR_STATE *es = NULL;
|
||||
CR_ERR_BUFFER *cr_err_buf = (CR_ERR_BUFFER *)id_buf;
|
||||
memset( cr_err_buf, 0, sizeof(CR_ERR_BUFFER) );
|
||||
@ -1081,8 +430,6 @@ int cr_generate_id( u32 serial[CR_NUM_OF_SERIAL], u8 id_buf[CR_ID_BUF_SIZE], u8
|
||||
|
||||
// リソースの解放
|
||||
if ( my_eckey ) EC_KEY_free( my_eckey );
|
||||
if ( my_evppkey ) EVP_PKEY_free( my_evppkey );
|
||||
if ( req ) X509_REQ_free( req );
|
||||
|
||||
ERR_remove_state(0);
|
||||
EVP_cleanup();
|
||||
|
||||
@ -116,7 +116,21 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#define DEBUG_PRINT 1
|
||||
#ifdef USE_HSM
|
||||
// nShield
|
||||
#include "nfastapp.h"
|
||||
#include "nfkm.h"
|
||||
#include "rqcard-applic.h"
|
||||
#include "rqcard-fips.h"
|
||||
// nShield optional
|
||||
#include "simplebignum.h"
|
||||
#endif // USE_HSM
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/ec.h>
|
||||
|
||||
|
||||
#define DEBUG_PRINT 1
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
#define DEBUG_PRINT_ARRAY DebugPrintArray
|
||||
@ -124,8 +138,47 @@ extern "C" {
|
||||
#define DEBUG_PRINT_ARRAY( ... ) ((void)0)
|
||||
#endif // DEBUG_PRINT
|
||||
|
||||
extern int crypto_aes_enc_dec( unsigned char *dst_buf, unsigned char *org_buf );
|
||||
extern int crypto_rsa_enc_dec( unsigned char *dst_buf, unsigned char *org_buf );
|
||||
|
||||
#define CR_GEN_ID_VERSION 1
|
||||
#define CR_RANDOM_LENGTH 0x50
|
||||
#define EC_PRIVATE_KEY_LENGTH 0x20
|
||||
#define ECDSA_SIGN_LENGTH 0x44
|
||||
#define CR_RSV_LENGTH 0x08
|
||||
#define EC_CURVE_NAME NID_sect233r1
|
||||
|
||||
typedef struct {
|
||||
u32 magic_number; /* 0x00 - 0x03 = 0xdeadb00f 確定!*/
|
||||
u32 serial[CR_NUM_OF_SERIAL]; /* 0x04 - 0x07 32bit device ID
|
||||
(32bit。1固定カウントアップ。)
|
||||
(本ID+randomの先頭0x1C bytesを組み合わせて、デバイス秘密鍵とする。)
|
||||
0x08 - 0x0F 64bit CTR番号 seed
|
||||
(34bitのみ使用。1~4の乱数カウントアップ)
|
||||
0x10 - 0x17 64bit 予備ID
|
||||
(64bitフルに使用。1~0x100000000の乱数カウントアップ)
|
||||
*/
|
||||
u8 version; /* 0x18 = CR_GEN_ID_VERSION = 1 */
|
||||
u8 bondingOption; /* 0x19 ボンディングオプション */
|
||||
u8 year; /* 0x1A デバイス証明書発行時間 (HSMから取得) */
|
||||
u8 month; /* 0x1B */
|
||||
u8 mday; /* 0x1C */
|
||||
u8 hour; /* 0x1D */
|
||||
u8 min; /* 0x1E */
|
||||
u8 sec; /* 0x1F */
|
||||
u8 devicePrivKey[ EC_PRIVATE_KEY_LENGTH ];
|
||||
/* 0x20 - 0x3F ECC233 private key (big endian) ユニーク性保証なし */
|
||||
u8 deviceCertSign[ ECDSA_SIGN_LENGTH ];
|
||||
/* 0x40 - 0x83 ECC233 ECDSA signature (big endian) */
|
||||
u32 deviceCertExpiryDate; /* 0x84 - 0x87 予約 */
|
||||
u8 reserved[ CR_RSV_LENGTH ]; /* 0x88 - 0x8F 予約 */
|
||||
u8 random[ CR_RANDOM_LENGTH ]; /* 0x90 - 0xDF 乱数 */
|
||||
u8 hash[ SHA256_DIGEST_LENGTH ]; /* 0xE0 - 0xFF "0x00-0xDF"領域のSHA256ハッシュ */
|
||||
} CR_ID_BUFFER; /* 合計256bytes = 2048bit */
|
||||
|
||||
|
||||
extern int GetTimestamp( u8 *pYear, u8 *pMonth, u8 *pMday, u8 *pHour, u8 *pMin, u8 *pSec, time_t *pTime);
|
||||
extern int GenerateRandom( u8 *pDst, int length );
|
||||
extern int GenarateECCKeyPair( EC_KEY *pECkey, u8 *pECPrivkey );
|
||||
extern int EncryptID( unsigned char *dst_buf, unsigned char *org_buf );
|
||||
extern void DebugPrintArray( char *pStr, const u8 *pData, int length );
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
312
cr_hsm_util.c
Normal file
312
cr_hsm_util.c
Normal file
@ -0,0 +1,312 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef USE_HSM
|
||||
// nShield
|
||||
#include "nfastapp.h"
|
||||
#include "nfkm.h"
|
||||
#include "rqcard-applic.h"
|
||||
#include "rqcard-fips.h"
|
||||
// nShield optional
|
||||
#include "simplebignum.h"
|
||||
#endif // USE_HSM
|
||||
|
||||
#include "cr_generate_id.h"
|
||||
#include "cr_generate_id_private.h"
|
||||
|
||||
#ifdef USE_HSM
|
||||
// functions
|
||||
static int hsm_get_rtc( time_t *time );
|
||||
static int hsm_set_rtc( struct timeval time );
|
||||
static int hsm_generate_random( unsigned char *buf, int bytes );
|
||||
#endif // USE_HSM
|
||||
|
||||
|
||||
// タイムスタンプの取得
|
||||
int GetTimestamp( u8 *pYear, u8 *pMonth, u8 *pMday, u8 *pHour, u8 *pMin, u8 *pSec, time_t *pTime)
|
||||
{
|
||||
int ret_code = 0;
|
||||
struct tm *tm_time;
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
#ifdef USE_HSM
|
||||
ret_code = hsm_get_rtc( &tv.tv_sec );
|
||||
if( ret_code != Status_OK ) {
|
||||
return ret_code;
|
||||
}
|
||||
#else // !USE_HSM
|
||||
gettimeofday(&tv,&tz);
|
||||
#endif // USE_HSM
|
||||
|
||||
tm_time = gmtime( &tv.tv_sec );
|
||||
|
||||
*pYear = (u8)tm_time->tm_year;
|
||||
*pMonth = (u8)tm_time->tm_mon+1;
|
||||
*pMday = (u8)tm_time->tm_mday;
|
||||
*pHour = (u8)tm_time->tm_hour;
|
||||
*pMin = (u8)tm_time->tm_min;
|
||||
*pSec = (u8)tm_time->tm_sec;
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
if( cr_print_flag ) {
|
||||
printf("GMT:%d-%02d-%02d %02d:%02d:%02d\n",
|
||||
*pYear+1900, /* 年 */
|
||||
*pMonth, /* 月 */
|
||||
*pMday, /* 日 */
|
||||
*pHour, /* 時 */
|
||||
*pMin, /* 分 */
|
||||
*pSec /* 秒 */
|
||||
);
|
||||
}
|
||||
#endif /* DEBUG_PRINT */
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_HSM
|
||||
// HSMのRTC値取得
|
||||
static int hsm_get_rtc( time_t *time )
|
||||
{
|
||||
int result;
|
||||
|
||||
M_Command cmd;
|
||||
M_Reply reply;
|
||||
|
||||
memset( &cmd, 0, sizeof( cmd ) );
|
||||
memset( &reply, 0, sizeof( reply ) );
|
||||
|
||||
cmd.cmd = Cmd_GetRTC;
|
||||
cmd.args.getrtc.module = HSM_MODULE_ID;
|
||||
|
||||
result = NFastApp_Transact( hsmConnection, NULL, &cmd, &reply, NULL );
|
||||
if ( result != Status_OK )
|
||||
{
|
||||
printf( "error(%d) : get rtc(transaction)\n", result );
|
||||
return result;
|
||||
}
|
||||
result = reply.status;
|
||||
if ( result != Status_OK )
|
||||
{
|
||||
printf( "error(%d) : get rtc(reply status)\n", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
*time = (int)reply.reply.getrtc.time.currenttimelow;
|
||||
|
||||
return 0;
|
||||
} // hsm_get_rtc
|
||||
|
||||
|
||||
#if 0
|
||||
// HSMのRTC値セット
|
||||
static int hsm_set_rtc( struct timeval time )
|
||||
{
|
||||
int result;
|
||||
|
||||
M_Command cmd;
|
||||
M_Reply reply;
|
||||
|
||||
memset( &cmd, 0, sizeof( cmd ) );
|
||||
memset( &reply, 0, sizeof( reply ) );
|
||||
|
||||
cmd.cmd = Cmd_SetRTC;
|
||||
cmd.args.setrtc.module = HSM_MODULE_ID;
|
||||
cmd.args.setrtc.time.currenttimelow = time.tv_sec;
|
||||
|
||||
result = NFastApp_Transact( hsmConnection, NULL, &cmd, &reply, NULL );
|
||||
if ( result != Status_OK )
|
||||
{
|
||||
printf( "error(%d) : set rtc(transaction)\n", result );
|
||||
return result;
|
||||
}
|
||||
result = reply.status;
|
||||
if ( result != Status_OK )
|
||||
{
|
||||
printf( "error(%d) : set rtc(reply status)\n", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // USE_HSM
|
||||
|
||||
|
||||
// ランダム値の生成
|
||||
int GenerateRandom( u8 *pDst, int length )
|
||||
{
|
||||
int ret_code = 0;
|
||||
|
||||
#ifdef USE_HSM
|
||||
ret_code = hsm_generate_random( pDst, CR_RANDOM_LENGTH );
|
||||
if ( ret_code != Status_OK )
|
||||
{
|
||||
printf( "error(%d) : hsm_generate_random\n", ret_code );
|
||||
return ret_code;
|
||||
}
|
||||
#else // !USE_HSM
|
||||
int i;
|
||||
for( i = 0 ; i < length; i++ ) {
|
||||
*pDst++ = (u8)rand();
|
||||
}
|
||||
#endif // USE_HSM
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_HSM
|
||||
// HSMから乱数を取得
|
||||
static int hsm_generate_random( unsigned char *buf, int bytes )
|
||||
{
|
||||
int ret_code;
|
||||
M_Command cmd;
|
||||
M_Reply reply;
|
||||
|
||||
memset( &cmd, 0, sizeof( cmd ) );
|
||||
memset( &reply, 0, sizeof( reply ) );
|
||||
|
||||
cmd.cmd = Cmd_GenerateRandom;
|
||||
cmd.args.generaterandom.lenbytes = bytes;
|
||||
ret_code = NFastApp_Transact( hsmConnection, NULL, &cmd, &reply, NULL );
|
||||
if ( ret_code != Status_OK )
|
||||
{
|
||||
printf( "error(%d) : generate random\n", ret_code );
|
||||
return ret_code;
|
||||
}
|
||||
ret_code = reply.status;
|
||||
if ( ret_code != Status_OK )
|
||||
{
|
||||
printf( "error(%d) : generate random reply\n", ret_code );
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
// buffer copy
|
||||
memcpy( buf, reply.reply.generaterandom.data.ptr, bytes );
|
||||
|
||||
NFastApp_Free_Command( hsmHandle, NULL, NULL, &cmd );
|
||||
NFastApp_Free_Reply( hsmHandle, NULL, NULL, &reply );
|
||||
|
||||
return 0;
|
||||
} // hsm_generate_rand
|
||||
#endif // USE_HSM
|
||||
|
||||
270
cr_keyPair.c
Normal file
270
cr_keyPair.c
Normal file
@ -0,0 +1,270 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h" // ec_key_st構造体の参照に必要
|
||||
#include "cr_generate_id.h"
|
||||
#include "cr_generate_id_private.h"
|
||||
|
||||
static int generate_EC_private_key( EC_KEY *eckey, u8 *privKey );
|
||||
static int generate_EC_public_key( EC_KEY *eckey );
|
||||
|
||||
|
||||
// ECCキーペアの生成
|
||||
int GenarateECCKeyPair( EC_KEY *pECkey, u8 *pECPrivkey )
|
||||
{
|
||||
int ret_code = 0;
|
||||
|
||||
// 楕円を選択 ( NID_X9_62_prime256v1 -> 32bytesまで、 NID_sect571r1 -> 71bytesまで 署名にデータを含められる )
|
||||
pECkey = EC_KEY_new_by_curve_name( NID_sect233r1 );
|
||||
if( pECkey == NULL )
|
||||
{
|
||||
return CR_GENID_ERROR_EC_KEY_NEW_1;
|
||||
}
|
||||
|
||||
// 秘密鍵生成
|
||||
ret_code = generate_EC_private_key( pECkey, pECPrivkey );
|
||||
if( ret_code != 0 )
|
||||
{
|
||||
return CR_GENID_ERROR_EC_GENERATE_PRIVATE_KEY;
|
||||
}
|
||||
|
||||
// 公開鍵生成
|
||||
ret_code = generate_EC_public_key( pECkey );
|
||||
if ( ret_code == 0 )
|
||||
{
|
||||
return CR_GENID_ERROR_EC_GENERATE_PUBLIC_KEY;
|
||||
}
|
||||
|
||||
// ASN.1 形式指定フラグをセットする
|
||||
// (これをセットしないと色々変なフィールドが入ってしまうため)
|
||||
EC_KEY_set_asn1_flag( pECkey, 1 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// EC秘密鍵を生成
|
||||
static int generate_EC_private_key( EC_KEY *eckey, u8 *privKey )
|
||||
{
|
||||
int ret_code = 0;
|
||||
BIGNUM *bn_privkey = NULL;
|
||||
|
||||
// 乱数を取得して、秘密鍵にする。
|
||||
ret_code = GenerateRandom( privKey, EC_PRIVATE_KEY_LENGTH );
|
||||
if ( ret_code != 0 ) {
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
// ECC233 で30バイトだけ利用するので、後ろ2バイトは0で埋める
|
||||
// (DER(BER) が big endian なので、ここでは先頭2byte)
|
||||
// + 7bit clear
|
||||
privKey[ 0 ] = 0;
|
||||
privKey[ 1 ] = 0;
|
||||
privKey[ 2 ] &= 0x01;
|
||||
|
||||
// 生成した秘密鍵をBNに変換して、eckeyにセット
|
||||
// ※bn_privkeyは、生成に成功した場合、ここではBN_freeされずにeckey要素の一つになって引き渡されます。
|
||||
bn_privkey = BN_new();
|
||||
if( bn_privkey == NULL )
|
||||
{
|
||||
return CR_GENID_ERROR_BN_NEW_0;
|
||||
}
|
||||
BN_init( bn_privkey ); /* memset(a,0,sizeof(BIGNUM)); */
|
||||
(void)BN_bin2bn( privKey, EC_PRIVATE_KEY_LENGTH, bn_privkey );
|
||||
eckey->priv_key = bn_privkey;
|
||||
|
||||
DEBUG_PRINT_ARRAY( "ec private key:", (const char *)privKey, EC_PRIVATE_KEY_LENGTH );
|
||||
|
||||
return ret_code;
|
||||
} // generate_EC_private_key
|
||||
|
||||
|
||||
// EC公開鍵を生成
|
||||
static int generate_EC_public_key( EC_KEY *eckey )
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *priv_key = NULL, *order = NULL;
|
||||
EC_POINT *pub_key = NULL;
|
||||
|
||||
if (!eckey || !eckey->group)
|
||||
{
|
||||
ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((order = BN_new()) == NULL) goto err;
|
||||
if ((ctx = BN_CTX_new()) == NULL) goto err;
|
||||
|
||||
if (eckey->priv_key == NULL)
|
||||
{
|
||||
priv_key = BN_new();
|
||||
if (priv_key == NULL) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
priv_key = eckey->priv_key;
|
||||
}
|
||||
|
||||
if (!EC_GROUP_get_order(eckey->group, order, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
#if 0 // 2009.09.25 これが実行されると、秘密鍵が乱数化されてしまい、指定した秘密鍵と変わってしまうためコメントアウトする。
|
||||
do
|
||||
if (!BN_rand_range(priv_key, order))
|
||||
goto err;
|
||||
while (BN_is_zero(priv_key));
|
||||
#endif
|
||||
|
||||
if (eckey->pub_key == NULL)
|
||||
{
|
||||
pub_key = EC_POINT_new(eckey->group);
|
||||
if (pub_key == NULL) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
pub_key = eckey->pub_key;
|
||||
|
||||
if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
eckey->priv_key = priv_key;
|
||||
eckey->pub_key = pub_key;
|
||||
|
||||
ok=1;
|
||||
|
||||
err:
|
||||
if (order)
|
||||
BN_free(order);
|
||||
if (pub_key != NULL && eckey->pub_key == NULL)
|
||||
EC_POINT_free(pub_key);
|
||||
if (priv_key != NULL && eckey->priv_key == NULL)
|
||||
BN_free(priv_key);
|
||||
if (ctx != NULL)
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return(ok);
|
||||
} // generate_EC_public_key
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user