TwlIPL_commit-99/build/tools/acsign/acsign.c
2023-12-16 15:41:34 -05:00

335 lines
8.5 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <string.h>
#include "format_sign.h"
#include "acsign.h"
// SHA1
#include "sha1dgst.c"
// RSA
// BN
#include "bn.h"
#include "bn_lib.c"
#include "bn_asm.c"
#include "bn_comba.c"
#include "bn_lsh.c"
#include "bn_rsh.c"
#include "bn_word.c"
#include "bn_add.c"
#include "bn_mul.c"
#include "bn_div.c"
#include "bn_exp.c"
#include "bn_sqr.c"
#include "bn_fm_w.c"
#include "bn_gcd.c"
#include "bn_ex_str.c"
#include "bn_ms_w.c"
//#include "bn_me.c"
#include "bn_rec.c"
#include "bn_mont.c"
#include "bn_recp.c"
#include "bn_wdiv.c"
#include "bn_r_exp.c"
#include "bn_m_exp.c"
#define BER_NULL 5
#define BER_OBJECT 6
#define BER_SEQUENCE 16
#define BER_OCTET_STRING 4
#define BER_CONSTRUCTED 0x20
/**
* Perform the EMSA-PKCS1_v1_5 padding
*
* @param random random context for seed data generation
* @param out destination buffer
* @param out_len length written to out
* @param in data to be padded
* @param in_len length of in
* @param flags mask of operation directives
*
* @pre out_len must contain length of data allocated to out
* @pre out must be the allocated the total length to be padded
*
* @note Method from PKCS#1 v2.1 standard 9.2.1 EMSA-PKCS1-v1_5
* @li In: Hash is hash funtion, hLen denotes length of octets of hash output
* @li In: M is message to be encoded
* @li In: emLen is intended length of octets
* @li Out: EM encoded message of length emLen
*
* @li Apply the hash function to message M to produce a hash value H
* If hash output is message to long the output message too long and
* stop
* @li Encode the algorithm ID for the hash in function into an ASN1 value
* @li if emLen < 10 + BER encoded message T output message length too short
* and stop
* @li generate octet string PS consisting of emLen - Length(T) - 2 octets
* with value FF
* @li Concatenate PS, DER encoding T and other padding such that EM is:
* 01 || PS || 00 || T
*
* @note it is the out layers responsibility to DER encode the
* data prior to padding as described in the first 2 steps in method
*/
//
// rsa_padding_add_pkcs1_type_1<5F>֐<EFBFBD><D690><EFBFBD><EFBFBD><EFBFBD>
//
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,j);
p[j]='\0';
return(0);
}
static void debug_dump(const void* buf, int len, const char* str, int line_elms)
{
const u8* bufp = (u8*)buf;
int i,ii;
if (str)
{
debug_printf("%s :\n", str);
}
for (i=0; i<=len/line_elms; i++)
{
if (i*line_elms >= len)
{
break;
}
for (ii=0; ii<line_elms; ii++)
{
if (i*line_elms+ii >= len)
{
break;
}
debug_printf("%02x ", bufp[i*line_elms+ii]);
}
debug_printf("\n");
}
}
//
// RSA
//
BOOL ACSign_Encrypto(void *sign, const void *key, const void *data, int length)
{
BN_CTX *ctx;
BIGNUM src, dst, exp, mod;
u8* key_exp = &((u8*)key)[ACS_RSA_PRVEXP_OFFSET];
u8* key_mod = &((u8*)key)[ACS_RSA_PRVMOD_OFFSET];
u8 buf[ACS_ENCRYPTED_HASH_LEN];
u32 len = length;
BOOL result = TRUE;
if (NULL == sign || NULL == key || NULL == data || 0 > length) {
return FALSE;
}
if ( add_padding( buf, ACS_ENCRYPTED_HASH_LEN, data, length ) ) {
debug_printf2("encode_padding was failed.\n");
result = FALSE;
goto end;
}
{
debug_dump(buf, ACS_ENCRYPTED_HASH_LEN, "padded hash", 16);
debug_dump(key_mod, ACS_RSA_PRVMOD_LEN, "key mod", 16);
debug_dump(key_exp, ACS_RSA_PRVEXP_LEN, "key exp", 16);
}
ctx = BN_CTX_new();
BN_init(&src);
BN_init(&dst);
BN_init(&exp);
BN_init(&mod);
BN_bin2bn((u8*)buf, ACS_ENCRYPTED_HASH_LEN, &src);
BN_bin2bn(key_exp, ACS_RSA_PRVEXP_LEN, &exp);
BN_bin2bn(key_mod, ACS_RSA_PRVMOD_LEN, &mod);
BN_mod_exp( &dst, &src, &exp, &mod, ctx );
len = BN_bn2bin( &dst, sign );
BN_free(&src);
BN_free(&dst);
BN_free(&exp);
BN_free(&mod);
if (ctx) {
BN_CTX_free(ctx);
}
if ( len != ACS_DECRYPTED_HASH_LEN ) {
result = FALSE;
goto end;
}
end:
return result;
}
BOOL ACSign_Decrypto(void *buf, const void *key, const void *sign, int length)
{
BN_CTX *ctx;
BIGNUM src, dst, exp, mod;
u32 key_exp = ACS_RSA_EXP;
u8* key_mod = &((u8*)key)[ACS_RSA_PRVMOD_OFFSET];
u8* bufp = (u8*)buf;
u32 len = length;
BOOL result = TRUE;
if (NULL == buf || NULL == key || NULL == sign || 0 > length) {
return FALSE;
}
ctx = BN_CTX_new();
BN_init(&src);
BN_init(&dst);
BN_init(&exp);
BN_init(&mod);
BN_bin2bn((u8*)sign, ACS_ENCRYPTED_HASH_LEN, &src);
BN_bin2bn((u8*)&key_exp, ACS_RSA_PUBEXP_LEN, &exp);
BN_bin2bn(key_mod, ACS_RSA_PRVMOD_LEN, &mod);
BN_mod_exp( &dst, &src, &exp, &mod, ctx );
len = BN_bn2bin( &dst, bufp );
BN_free(&src);
BN_free(&dst);
BN_free(&exp);
BN_free(&mod);
if (ctx) {
BN_CTX_free(ctx);
}
if ( len != ACS_DECRYPTED_HASH_LEN ) {
result = FALSE;
goto end;
}
end:
return result;
}
//
int ACSign_DigestUnit(
void* buffer, // <20>o<EFBFBD>͗̈<CD97>
const void* buf, // <20>f<EFBFBD>[<5B>^<5E>ւ̃|<7C>C<EFBFBD><43><EFBFBD>^
unsigned int len // <20>f<EFBFBD>[<5B>^<5E>̒<EFBFBD><CC92><EFBFBD>
)
{
HASHContext context;
unsigned char *bufferp = buffer;
HASHReset( &context );
HASHUpdate( &context, buf, len );
HASHGetDigest( &context, bufferp );
return TRUE;
}
//
int ACSign_CompareUnit(
const void* decedHash, // ACSign_Decrypto<74>̏o<CC8F><6F>
const void* digest // ACSign_DigestUnit<69>̏o<CC8F><6F>
)
{
const unsigned char* dgt = digest;
const unsigned char* dgtCmp = decedHash;
int i;
int test = TRUE;
if ( !decedHash ) return FALSE;
if ( !digest ) return FALSE;
for ( i = 0; i < ACS_HASH_LEN; i++ )
{
if ( *dgt++ != *dgtCmp++ )
{
test = FALSE;
break;
}
}
return test;
}
/*
<20>C<EFBFBD>Ӄo<D383>C<EFBFBD>g<EFBFBD><67><EFBFBD>̓<EFBFBD><CC93>̓f<CD83>[<5B>^<5E><><EFBFBD><EFBFBD>
<20>C<EFBFBD>Ӄo<D383>C<EFBFBD>g<EFBFBD><67><EFBFBD>̏o<CC8F>̓f<CD83>[<5B>^<5E>𓾂܂<F093BE82><DC82>B
<20>΂<EFBFBD><CE82>Ă<EFBFBD><C482><EFBFBD><E982A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882><EFBFBD><EFBFBD>͒l<CD92><6C><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD>Ȓl<C892>Ƀ}<7D>b<EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD><E982BE><EFBFBD>ł<EFBFBD><C582>B
<20><><EFBFBD>o<EFBFBD>̓<EFBFBD><CD83><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԃ<EFBFBD><D482>Ă<EFBFBD><C482>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD>
*/
int ACSign_GetKey(
void* dest_ptr, // <20>o<EFBFBD>̓f<CD83>[<5B>^<5E>ւ̃|<7C>C<EFBFBD><43><EFBFBD>^
unsigned int dest_len, // <20>o<EFBFBD>̓f<CD83>[<5B>^<5E>̒<EFBFBD><CC92><EFBFBD>
const void* src_ptr, // <20><><EFBFBD>̓f<CD83>[<5B>^<5E>ւ̃|<7C>C<EFBFBD><43><EFBFBD>^
unsigned int src_len // <20><><EFBFBD>̓f<CD83>[<5B>^<5E>̒<EFBFBD><CC92><EFBFBD>
)
{
HASHContext ctx;
unsigned char *ptr;
unsigned char state[ACS_HASH_LEN];
unsigned char output[ACS_HASH_LEN];
int i;
if (dest_ptr == NULL)
return 1;
if (src_ptr == NULL && src_len > 0)
return 0;
HASHReset(&ctx);
HASHUpdate(&ctx, src_ptr, src_len);
HASHGetDigest(&ctx, state);
ptr = dest_ptr;
while (dest_len > 0)
{
unsigned int len = dest_len < ACS_HASH_LEN ? dest_len : ACS_HASH_LEN;
// plus one
for (i = 0; i < ACS_HASH_LEN; i++)
{
if (state[ACS_HASH_LEN-1-i]++)
break;
}
HASHUpdate(&ctx, state, ACS_HASH_LEN);
HASHGetDigest(&ctx, output);
memcpy(ptr, output, len);
ptr += len;
dest_len -= len;
}
memset(state, 0, ACS_HASH_LEN);
memset(output, 0, ACS_HASH_LEN);
return 1;
}