mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-25 23:20:15 +00:00
Use Citra as local debugger
This commit is contained in:
parent
a53714acd3
commit
dc4ebfbac0
@ -270,6 +270,9 @@ if (MSVC)
|
|||||||
add_subdirectory(externals/getopt)
|
add_subdirectory(externals/getopt)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(externals/ctrtool)
|
||||||
|
include_directories(externals/ctrltool)
|
||||||
|
|
||||||
# process subdirectories
|
# process subdirectories
|
||||||
add_subdirectory(externals/soundtouch)
|
add_subdirectory(externals/soundtouch)
|
||||||
|
|
||||||
|
24
externals/ctrtool/CMakeLists.txt
vendored
Normal file
24
externals/ctrtool/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
set(SRCS
|
||||||
|
ctr.c
|
||||||
|
polarssl/aes.c
|
||||||
|
polarssl/bignum.c
|
||||||
|
polarssl/rsa.c
|
||||||
|
polarssl/sha2.c
|
||||||
|
)
|
||||||
|
set(HEADERS
|
||||||
|
ctr.h
|
||||||
|
keyset.h
|
||||||
|
polarssl/aes.h
|
||||||
|
polarssl/bignum.h
|
||||||
|
polarssl/bn_mul.h
|
||||||
|
polarssl/config.h
|
||||||
|
polarssl/padlock.h
|
||||||
|
polarssl/rsa.h
|
||||||
|
polarssl/sha2.h
|
||||||
|
types.h
|
||||||
|
)
|
||||||
|
|
||||||
|
create_directory_groups(${SRCS} ${HEADERS})
|
||||||
|
add_library(ctrtool ${SRCS} ${HEADERS})
|
||||||
|
target_compile_definitions(ctrtool PUBLIC STATIC_GETOPT)
|
||||||
|
target_include_directories(ctrtool INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
354
externals/ctrtool/ctr.c
vendored
Normal file
354
externals/ctrtool/ctr.c
vendored
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "ctr.h"
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_set_iv( ctr_aes_context* ctx,
|
||||||
|
u8 iv[16] )
|
||||||
|
{
|
||||||
|
memcpy(ctx->iv, iv, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ctr_add_counter( ctr_aes_context* ctx,
|
||||||
|
u32 carry )
|
||||||
|
{
|
||||||
|
u32 counter[4];
|
||||||
|
u32 sum;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0; i<4; i++)
|
||||||
|
counter[i] = (ctx->ctr[i*4+0]<<24) | (ctx->ctr[i*4+1]<<16) | (ctx->ctr[i*4+2]<<8) | (ctx->ctr[i*4+3]<<0);
|
||||||
|
|
||||||
|
for(i=3; i>=0; i--)
|
||||||
|
{
|
||||||
|
sum = counter[i] + carry;
|
||||||
|
|
||||||
|
if (sum < counter[i])
|
||||||
|
carry = 1;
|
||||||
|
else
|
||||||
|
carry = 0;
|
||||||
|
|
||||||
|
counter[i] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<4; i++)
|
||||||
|
{
|
||||||
|
ctx->ctr[i*4+0] = counter[i]>>24;
|
||||||
|
ctx->ctr[i*4+1] = counter[i]>>16;
|
||||||
|
ctx->ctr[i*4+2] = counter[i]>>8;
|
||||||
|
ctx->ctr[i*4+3] = counter[i]>>0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ctr_set_counter( ctr_aes_context* ctx,
|
||||||
|
u8 ctr[16] )
|
||||||
|
{
|
||||||
|
memcpy(ctx->ctr, ctr, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_init_counter( ctr_aes_context* ctx,
|
||||||
|
u8 key[16],
|
||||||
|
u8 ctr[16] )
|
||||||
|
{
|
||||||
|
aes_setkey_enc(&ctx->aes, key, 128);
|
||||||
|
ctr_set_counter(ctx, ctr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_crypt_counter_block( ctr_aes_context* ctx,
|
||||||
|
u8 input[16],
|
||||||
|
u8 output[16] )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u8 stream[16];
|
||||||
|
|
||||||
|
|
||||||
|
aes_crypt_ecb(&ctx->aes, AES_ENCRYPT, ctx->ctr, stream);
|
||||||
|
|
||||||
|
|
||||||
|
if (input)
|
||||||
|
{
|
||||||
|
for(i=0; i<16; i++)
|
||||||
|
{
|
||||||
|
output[i] = stream[i] ^ input[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(i=0; i<16; i++)
|
||||||
|
output[i] = stream[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
ctr_add_counter(ctx, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_crypt_counter( ctr_aes_context* ctx,
|
||||||
|
u8* input,
|
||||||
|
u8* output,
|
||||||
|
u32 size )
|
||||||
|
{
|
||||||
|
u8 stream[16];
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
while(size >= 16)
|
||||||
|
{
|
||||||
|
ctr_crypt_counter_block(ctx, input, output);
|
||||||
|
|
||||||
|
if (input)
|
||||||
|
input += 16;
|
||||||
|
if (output)
|
||||||
|
output += 16;
|
||||||
|
|
||||||
|
size -= 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
{
|
||||||
|
memset(stream, 0, 16);
|
||||||
|
ctr_crypt_counter_block(ctx, stream, stream);
|
||||||
|
|
||||||
|
if (input)
|
||||||
|
{
|
||||||
|
for(i=0; i<size; i++)
|
||||||
|
output[i] = input[i] ^ stream[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(output, stream, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ctr_init_cbc_encrypt( ctr_aes_context* ctx,
|
||||||
|
u8 key[16],
|
||||||
|
u8 iv[16] )
|
||||||
|
{
|
||||||
|
aes_setkey_enc(&ctx->aes, key, 128);
|
||||||
|
ctr_set_iv(ctx, iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ctr_init_cbc_decrypt( ctr_aes_context* ctx,
|
||||||
|
u8 key[16],
|
||||||
|
u8 iv[16] )
|
||||||
|
{
|
||||||
|
aes_setkey_dec(&ctx->aes, key, 128);
|
||||||
|
ctr_set_iv(ctx, iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ctr_encrypt_cbc( ctr_aes_context* ctx,
|
||||||
|
u8* input,
|
||||||
|
u8* output,
|
||||||
|
u32 size )
|
||||||
|
{
|
||||||
|
aes_crypt_cbc(&ctx->aes, AES_ENCRYPT, size, ctx->iv, input, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ctr_decrypt_cbc( ctr_aes_context* ctx,
|
||||||
|
u8* input,
|
||||||
|
u8* output,
|
||||||
|
u32 size )
|
||||||
|
{
|
||||||
|
aes_crypt_cbc(&ctx->aes, AES_DECRYPT, size, ctx->iv, input, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ctr_sha_256( const u8* data,
|
||||||
|
u32 size,
|
||||||
|
u8 hash[0x20] )
|
||||||
|
{
|
||||||
|
sha2(data, size, hash, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ctr_sha_256_verify( const u8* data,
|
||||||
|
u32 size,
|
||||||
|
const u8 checkhash[0x20] )
|
||||||
|
{
|
||||||
|
u8 hash[0x20];
|
||||||
|
|
||||||
|
sha2(data, size, hash, 0);
|
||||||
|
|
||||||
|
if (memcmp(hash, checkhash, 0x20) == 0)
|
||||||
|
return Good;
|
||||||
|
else
|
||||||
|
return Fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ctr_sha_256_init( ctr_sha256_context* ctx )
|
||||||
|
{
|
||||||
|
sha2_starts(&ctx->sha, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ctr_sha_256_update( ctr_sha256_context* ctx,
|
||||||
|
const u8* data,
|
||||||
|
u32 size )
|
||||||
|
{
|
||||||
|
sha2_update(&ctx->sha, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_sha_256_finish( ctr_sha256_context* ctx,
|
||||||
|
u8 hash[0x20] )
|
||||||
|
{
|
||||||
|
sha2_finish(&ctx->sha, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_rsa_init_key_pubmodulus(rsakey2048* key, u8 modulus[0x100])
|
||||||
|
{
|
||||||
|
u8 exponent[3] = {0x01, 0x00, 0x01};
|
||||||
|
|
||||||
|
ctr_rsa_init_key_pub(key, modulus, exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ctr_rsa_init_key_pub(rsakey2048* key, u8 modulus[0x100], u8 exponent[3])
|
||||||
|
{
|
||||||
|
key->keytype = RSAKEY_PUB;
|
||||||
|
memcpy(key->n, modulus, 0x100);
|
||||||
|
memcpy(key->e, exponent, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ctr_rsa_init(ctr_rsa_context* ctx, rsakey2048* key)
|
||||||
|
{
|
||||||
|
rsa_init(&ctx->rsa, RSA_PKCS_V15, 0);
|
||||||
|
ctx->rsa.len = 0x100;
|
||||||
|
|
||||||
|
if (key->keytype == RSAKEY_INVALID)
|
||||||
|
goto clean;
|
||||||
|
|
||||||
|
if (mpi_read_binary(&ctx->rsa.N, key->n, sizeof(key->n)))
|
||||||
|
goto clean;
|
||||||
|
if (mpi_read_binary(&ctx->rsa.E, key->e, sizeof(key->e)))
|
||||||
|
goto clean;
|
||||||
|
if (rsa_check_pubkey(&ctx->rsa))
|
||||||
|
goto clean;
|
||||||
|
|
||||||
|
if (key->keytype == RSAKEY_PRIV)
|
||||||
|
{
|
||||||
|
if (mpi_read_binary(&ctx->rsa.D, key->d, sizeof(key->d)))
|
||||||
|
goto clean;
|
||||||
|
if (mpi_read_binary(&ctx->rsa.P, key->p, sizeof(key->p)))
|
||||||
|
goto clean;
|
||||||
|
if (mpi_read_binary(&ctx->rsa.Q, key->q, sizeof(key->q)))
|
||||||
|
goto clean;
|
||||||
|
if (mpi_read_binary(&ctx->rsa.DP, key->dp, sizeof(key->dp)))
|
||||||
|
goto clean;
|
||||||
|
if (mpi_read_binary(&ctx->rsa.DQ, key->dq, sizeof(key->dq)))
|
||||||
|
goto clean;
|
||||||
|
if (mpi_read_binary(&ctx->rsa.QP, key->qp, sizeof(key->qp)))
|
||||||
|
goto clean;
|
||||||
|
if (rsa_check_privkey(&ctx->rsa))
|
||||||
|
goto clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
clean:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ctr_rsa_verify_hash(const u8 signature[0x100], const u8 hash[0x20], rsakey2048* key)
|
||||||
|
{
|
||||||
|
ctr_rsa_context ctx;
|
||||||
|
u32 result;
|
||||||
|
u8 output[0x100];
|
||||||
|
|
||||||
|
if (key->keytype == RSAKEY_INVALID)
|
||||||
|
return Fail;
|
||||||
|
|
||||||
|
ctr_rsa_init(&ctx, key);
|
||||||
|
// memset(output, 0, 0x100);
|
||||||
|
// result = ctr_rsa_public(signature, output, key);
|
||||||
|
// printf("Result = %d\n", result);
|
||||||
|
// memdump(stdout, "output: ", output, 0x100);
|
||||||
|
|
||||||
|
result = rsa_pkcs1_verify(&ctx.rsa, RSA_PUBLIC, SIG_RSA_SHA256, 0x20, hash, (u8*)signature);
|
||||||
|
|
||||||
|
ctr_rsa_free(&ctx);
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
return Good;
|
||||||
|
else
|
||||||
|
return Fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ctr_rsa_sign_hash(const u8 hash[0x20], u8 signature[0x100], rsakey2048* key)
|
||||||
|
{
|
||||||
|
ctr_rsa_context ctx;
|
||||||
|
u32 result;
|
||||||
|
|
||||||
|
ctr_rsa_init(&ctx, key);
|
||||||
|
|
||||||
|
result = rsa_pkcs1_verify(&ctx.rsa, RSA_PUBLIC, SIG_RSA_SHA256, 0x20, hash, (u8*)signature);
|
||||||
|
result = rsa_pkcs1_sign(&ctx.rsa, RSA_PRIVATE, SIG_RSA_SHA256, 0x20, hash, signature);
|
||||||
|
|
||||||
|
ctr_rsa_free(&ctx);
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ctr_rsa_public(const u8 signature[0x100], u8 output[0x100], rsakey2048* key)
|
||||||
|
{
|
||||||
|
ctr_rsa_context ctx;
|
||||||
|
u32 result;
|
||||||
|
|
||||||
|
ctr_rsa_init(&ctx, key);
|
||||||
|
|
||||||
|
result = rsa_public(&ctx.rsa, signature, output);
|
||||||
|
|
||||||
|
ctr_rsa_free(&ctx);
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_rsa_free(ctr_rsa_context* ctx)
|
||||||
|
{
|
||||||
|
rsa_free(&ctx->rsa);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate DP, DQ, QP based on private key
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
static int ctr_rsa_key_init(ctr_rsa_context* ctx )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
mpi P1, Q1;
|
||||||
|
|
||||||
|
mpi_init( &P1, &Q1, NULL );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_sub_int( &P1, &ctx->rsa.P, 1 ) );
|
||||||
|
MPI_CHK( mpi_sub_int( &Q1, &ctx->rsa.Q, 1 ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DP = D mod (P - 1)
|
||||||
|
* DQ = D mod (Q - 1)
|
||||||
|
* QP = Q^-1 mod P
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->rsa.DP, &ctx->rsa.D, &P1 ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->rsa.DQ, &ctx->rsa.D, &Q1 ) );
|
||||||
|
MPI_CHK( mpi_inv_mod( &ctx->rsa.QP, &ctx->rsa.Q, &ctx->rsa.P ) );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
mpi_free(&Q1, &P1, NULL );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
rsa_free( &ctx->rsa );
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_GEN_FAILED | ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
#endif
|
146
externals/ctrtool/ctr.h
vendored
Normal file
146
externals/ctrtool/ctr.h
vendored
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#ifndef _CTR_H_
|
||||||
|
#define _CTR_H_
|
||||||
|
|
||||||
|
#include "polarssl/aes.h"
|
||||||
|
#include "polarssl/rsa.h"
|
||||||
|
#include "polarssl/sha2.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "keyset.h"
|
||||||
|
|
||||||
|
#define MAGIC_NCCH 0x4843434E
|
||||||
|
#define MAGIC_NCSD 0x4453434E
|
||||||
|
#define MAGIC_FIRM 0x4D524946
|
||||||
|
#define MAGIC_CWAV 0x56415743
|
||||||
|
#define MAGIC_IVFC 0x43465649
|
||||||
|
|
||||||
|
#define SIZE_128MB (128 * 1024 * 1024)
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
FILETYPE_UNKNOWN = 0,
|
||||||
|
FILETYPE_CCI,
|
||||||
|
FILETYPE_CXI,
|
||||||
|
FILETYPE_CIA,
|
||||||
|
FILETYPE_EXHEADER,
|
||||||
|
FILETYPE_TMD,
|
||||||
|
FILETYPE_LZSS,
|
||||||
|
FILETYPE_FIRM,
|
||||||
|
FILETYPE_CWAV,
|
||||||
|
FILETYPE_ROMFS
|
||||||
|
} ctr_filetypes;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u8 ctr[16];
|
||||||
|
u8 iv[16];
|
||||||
|
aes_context aes;
|
||||||
|
} ctr_aes_context;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
rsa_context rsa;
|
||||||
|
} ctr_rsa_context;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
sha2_context sha;
|
||||||
|
} ctr_sha256_context;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ctr_set_iv( ctr_aes_context* ctx,
|
||||||
|
u8 iv[16] );
|
||||||
|
|
||||||
|
void ctr_add_counter( ctr_aes_context* ctx,
|
||||||
|
u32 carry );
|
||||||
|
|
||||||
|
void ctr_set_counter( ctr_aes_context* ctx,
|
||||||
|
u8 ctr[16] );
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_init_counter( ctr_aes_context* ctx,
|
||||||
|
u8 key[16],
|
||||||
|
u8 ctr[16] );
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_crypt_counter_block( ctr_aes_context* ctx,
|
||||||
|
u8 input[16],
|
||||||
|
u8 output[16] );
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_crypt_counter( ctr_aes_context* ctx,
|
||||||
|
u8* input,
|
||||||
|
u8* output,
|
||||||
|
u32 size );
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_init_cbc_encrypt( ctr_aes_context* ctx,
|
||||||
|
u8 key[16],
|
||||||
|
u8 iv[16] );
|
||||||
|
|
||||||
|
void ctr_init_cbc_decrypt( ctr_aes_context* ctx,
|
||||||
|
u8 key[16],
|
||||||
|
u8 iv[16] );
|
||||||
|
|
||||||
|
void ctr_encrypt_cbc( ctr_aes_context* ctx,
|
||||||
|
u8* input,
|
||||||
|
u8* output,
|
||||||
|
u32 size );
|
||||||
|
|
||||||
|
void ctr_decrypt_cbc( ctr_aes_context* ctx,
|
||||||
|
u8* input,
|
||||||
|
u8* output,
|
||||||
|
u32 size );
|
||||||
|
|
||||||
|
void ctr_rsa_init_key_pubmodulus( rsakey2048* key,
|
||||||
|
u8 modulus[0x100] );
|
||||||
|
|
||||||
|
void ctr_rsa_init_key_pub( rsakey2048* key,
|
||||||
|
u8 modulus[0x100],
|
||||||
|
u8 exponent[3] );
|
||||||
|
|
||||||
|
int ctr_rsa_init( ctr_rsa_context* ctx,
|
||||||
|
rsakey2048* key );
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_rsa_free( ctr_rsa_context* ctx );
|
||||||
|
|
||||||
|
int ctr_rsa_verify_hash( const u8 signature[0x100],
|
||||||
|
const u8 hash[0x20],
|
||||||
|
rsakey2048* key);
|
||||||
|
|
||||||
|
int ctr_rsa_sign_hash( const u8 hash[0x20],
|
||||||
|
u8 signature[0x100],
|
||||||
|
rsakey2048* key );
|
||||||
|
|
||||||
|
int ctr_rsa_public( const u8 signature[0x100],
|
||||||
|
u8 output[0x100],
|
||||||
|
rsakey2048* key );
|
||||||
|
|
||||||
|
void ctr_sha_256( const u8* data,
|
||||||
|
u32 size,
|
||||||
|
u8 hash[0x20] );
|
||||||
|
|
||||||
|
int ctr_sha_256_verify( const u8* data,
|
||||||
|
u32 size,
|
||||||
|
const u8 checkhash[0x20] );
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_sha_256_init( ctr_sha256_context* ctx );
|
||||||
|
|
||||||
|
void ctr_sha_256_update( ctr_sha256_context* ctx,
|
||||||
|
const u8* data,
|
||||||
|
u32 size );
|
||||||
|
|
||||||
|
|
||||||
|
void ctr_sha_256_finish( ctr_sha256_context* ctx,
|
||||||
|
u8 hash[0x20] );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _CTR_H_
|
70
externals/ctrtool/keyset.h
vendored
Normal file
70
externals/ctrtool/keyset.h
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#ifndef _KEYSET_H_
|
||||||
|
#define _KEYSET_H_
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
KEY_ERR_LEN_MISMATCH,
|
||||||
|
KEY_ERR_INVALID_NODE,
|
||||||
|
KEY_OK
|
||||||
|
} keystatus;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
RSAKEY_INVALID,
|
||||||
|
RSAKEY_PRIV,
|
||||||
|
RSAKEY_PUB
|
||||||
|
} rsakeytype;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char n[256];
|
||||||
|
unsigned char e[3];
|
||||||
|
unsigned char d[256];
|
||||||
|
unsigned char p[128];
|
||||||
|
unsigned char q[128];
|
||||||
|
unsigned char dp[128];
|
||||||
|
unsigned char dq[128];
|
||||||
|
unsigned char qp[128];
|
||||||
|
rsakeytype keytype;
|
||||||
|
} rsakey2048;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char data[16];
|
||||||
|
int valid;
|
||||||
|
} key128;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
key128 commonkey;
|
||||||
|
key128 ncchkey;
|
||||||
|
key128 ncchfixedsystemkey;
|
||||||
|
rsakey2048 ncsdrsakey;
|
||||||
|
rsakey2048 ncchrsakey;
|
||||||
|
rsakey2048 ncchdescrsakey;
|
||||||
|
rsakey2048 firmrsakey;
|
||||||
|
} keyset;
|
||||||
|
|
||||||
|
void keyset_init(keyset* keys);
|
||||||
|
int keyset_load(keyset* keys, const char* fname, int verbose);
|
||||||
|
void keyset_merge(keyset* keys, keyset* src);
|
||||||
|
void keyset_set_commonkey(keyset* keys, unsigned char* keydata);
|
||||||
|
void keyset_parse_commonkey(keyset* keys, char* keytext, int keylen);
|
||||||
|
void keyset_set_ncchkey(keyset* keys, unsigned char* keydata);
|
||||||
|
void keyset_parse_ncchkey(keyset* keys, char* keytext, int keylen);
|
||||||
|
void keyset_set_ncchfixedsystemkey(keyset* keys, unsigned char* keydata);
|
||||||
|
void keyset_parse_ncchfixedsystemkey(keyset* keys, char* keytext, int keylen);
|
||||||
|
void keyset_dump(keyset* keys);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _KEYSET_H_
|
1164
externals/ctrtool/polarssl/aes.c
vendored
Normal file
1164
externals/ctrtool/polarssl/aes.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
139
externals/ctrtool/polarssl/aes.h
vendored
Normal file
139
externals/ctrtool/polarssl/aes.h
vendored
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/**
|
||||||
|
* \file aes.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2010, Brainspark B.V.
|
||||||
|
*
|
||||||
|
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||||
|
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
#ifndef POLARSSL_AES_H
|
||||||
|
#define POLARSSL_AES_H
|
||||||
|
|
||||||
|
#define AES_ENCRYPT 1
|
||||||
|
#define AES_DECRYPT 0
|
||||||
|
|
||||||
|
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0800
|
||||||
|
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0810
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES context structure
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int nr; /*!< number of rounds */
|
||||||
|
unsigned long *rk; /*!< AES round keys */
|
||||||
|
unsigned long buf[68]; /*!< unaligned data */
|
||||||
|
}
|
||||||
|
aes_context;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES key schedule (encryption)
|
||||||
|
*
|
||||||
|
* \param ctx AES context to be initialized
|
||||||
|
* \param key encryption key
|
||||||
|
* \param keysize must be 128, 192 or 256
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||||
|
*/
|
||||||
|
int aes_setkey_enc( aes_context *ctx, const unsigned char *key, int keysize );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES key schedule (decryption)
|
||||||
|
*
|
||||||
|
* \param ctx AES context to be initialized
|
||||||
|
* \param key decryption key
|
||||||
|
* \param keysize must be 128, 192 or 256
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||||
|
*/
|
||||||
|
int aes_setkey_dec( aes_context *ctx, const unsigned char *key, int keysize );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES-ECB block encryption/decryption
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
* \param input 16-byte input block
|
||||||
|
* \param output 16-byte output block
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*/
|
||||||
|
int aes_crypt_ecb( aes_context *ctx,
|
||||||
|
int mode,
|
||||||
|
const unsigned char input[16],
|
||||||
|
unsigned char output[16] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES-CBC buffer encryption/decryption
|
||||||
|
* Length should be a multiple of the block
|
||||||
|
* size (16 bytes)
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
* \param length length of the input data
|
||||||
|
* \param iv initialization vector (updated after use)
|
||||||
|
* \param input buffer holding the input data
|
||||||
|
* \param output buffer holding the output data
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
|
||||||
|
*/
|
||||||
|
int aes_crypt_cbc( aes_context *ctx,
|
||||||
|
int mode,
|
||||||
|
int length,
|
||||||
|
unsigned char iv[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief AES-CFB128 buffer encryption/decryption.
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
* \param length length of the input data
|
||||||
|
* \param iv_off offset in IV (updated after use)
|
||||||
|
* \param iv initialization vector (updated after use)
|
||||||
|
* \param input buffer holding the input data
|
||||||
|
* \param output buffer holding the output data
|
||||||
|
*
|
||||||
|
* \return 0 if successful
|
||||||
|
*/
|
||||||
|
int aes_crypt_cfb128( aes_context *ctx,
|
||||||
|
int mode,
|
||||||
|
int length,
|
||||||
|
int *iv_off,
|
||||||
|
unsigned char iv[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checkup routine
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or 1 if the test failed
|
||||||
|
*/
|
||||||
|
int aes_self_test( int verbose );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* aes.h */
|
2038
externals/ctrtool/polarssl/bignum.c
vendored
Normal file
2038
externals/ctrtool/polarssl/bignum.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
533
externals/ctrtool/polarssl/bignum.h
vendored
Normal file
533
externals/ctrtool/polarssl/bignum.h
vendored
Normal file
@ -0,0 +1,533 @@
|
|||||||
|
/**
|
||||||
|
* \file bignum.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2010, Brainspark B.V.
|
||||||
|
*
|
||||||
|
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||||
|
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
#ifndef POLARSSL_BIGNUM_H
|
||||||
|
#define POLARSSL_BIGNUM_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define POLARSSL_ERR_MPI_FILE_IO_ERROR 0x0002
|
||||||
|
#define POLARSSL_ERR_MPI_BAD_INPUT_DATA 0x0004
|
||||||
|
#define POLARSSL_ERR_MPI_INVALID_CHARACTER 0x0006
|
||||||
|
#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL 0x0008
|
||||||
|
#define POLARSSL_ERR_MPI_NEGATIVE_VALUE 0x000A
|
||||||
|
#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO 0x000C
|
||||||
|
#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE 0x000E
|
||||||
|
|
||||||
|
#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the base integer type, architecture-wise
|
||||||
|
*/
|
||||||
|
#if defined(POLARSSL_HAVE_INT8)
|
||||||
|
typedef unsigned char t_int;
|
||||||
|
typedef unsigned short t_dbl;
|
||||||
|
#else
|
||||||
|
#if defined(POLARSSL_HAVE_INT16)
|
||||||
|
typedef unsigned short t_int;
|
||||||
|
typedef unsigned long t_dbl;
|
||||||
|
#else
|
||||||
|
typedef unsigned long t_int;
|
||||||
|
#if defined(_MSC_VER) && defined(_M_IX86)
|
||||||
|
typedef unsigned __int64 t_dbl;
|
||||||
|
#else
|
||||||
|
#if defined(__amd64__) || defined(__x86_64__) || \
|
||||||
|
defined(__ppc64__) || defined(__powerpc64__) || \
|
||||||
|
defined(__ia64__) || defined(__alpha__)
|
||||||
|
typedef unsigned int t_dbl __attribute__((mode(TI)));
|
||||||
|
#else
|
||||||
|
#if defined(POLARSSL_HAVE_LONGLONG)
|
||||||
|
typedef unsigned long long t_dbl;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MPI structure
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int s; /*!< integer sign */
|
||||||
|
int n; /*!< total # of limbs */
|
||||||
|
t_int *p; /*!< pointer to limbs */
|
||||||
|
}
|
||||||
|
mpi;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize one or more mpi
|
||||||
|
*/
|
||||||
|
void mpi_init( mpi *X, ... );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Unallocate one or more mpi
|
||||||
|
*/
|
||||||
|
void mpi_free( mpi *X, ... );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Enlarge to the specified number of limbs
|
||||||
|
*
|
||||||
|
* \param X MPI to grow
|
||||||
|
* \param nblimbs The target number of limbs
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_grow( mpi *X, int nblimbs );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Copy the contents of Y into X
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param Y Source MPI
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_copy( mpi *X, const mpi *Y );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Swap the contents of X and Y
|
||||||
|
*
|
||||||
|
* \param X First MPI value
|
||||||
|
* \param Y Second MPI value
|
||||||
|
*/
|
||||||
|
void mpi_swap( mpi *X, mpi *Y );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set value from integer
|
||||||
|
*
|
||||||
|
* \param X MPI to set
|
||||||
|
* \param z Value to use
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_lset( mpi *X, int z );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the number of least significant bits
|
||||||
|
*
|
||||||
|
* \param X MPI to use
|
||||||
|
*/
|
||||||
|
int mpi_lsb( const mpi *X );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the number of most significant bits
|
||||||
|
*
|
||||||
|
* \param X MPI to use
|
||||||
|
*/
|
||||||
|
int mpi_msb( const mpi *X );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return the total size in bytes
|
||||||
|
*
|
||||||
|
* \param X MPI to use
|
||||||
|
*/
|
||||||
|
int mpi_size( const mpi *X );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Import from an ASCII string
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param radix Input numeric base
|
||||||
|
* \param s Null-terminated string buffer
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
|
||||||
|
*/
|
||||||
|
int mpi_read_string( mpi *X, int radix, const char *s );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Export into an ASCII string
|
||||||
|
*
|
||||||
|
* \param X Source MPI
|
||||||
|
* \param radix Output numeric base
|
||||||
|
* \param s String buffer
|
||||||
|
* \param slen String buffer size
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code.
|
||||||
|
* *slen is always updated to reflect the amount
|
||||||
|
* of data that has (or would have) been written.
|
||||||
|
*
|
||||||
|
* \note Call this function with *slen = 0 to obtain the
|
||||||
|
* minimum required buffer size in *slen.
|
||||||
|
*/
|
||||||
|
int mpi_write_string( const mpi *X, int radix, char *s, int *slen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Read X from an opened file
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param radix Input numeric base
|
||||||
|
* \param fin Input file handle
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
|
||||||
|
*/
|
||||||
|
int mpi_read_file( mpi *X, int radix, FILE *fin );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Write X into an opened file, or stdout if fout is NULL
|
||||||
|
*
|
||||||
|
* \param p Prefix, can be NULL
|
||||||
|
* \param X Source MPI
|
||||||
|
* \param radix Output numeric base
|
||||||
|
* \param fout Output file handle (can be NULL)
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
|
||||||
|
*
|
||||||
|
* \note Set fout == NULL to print X on the console.
|
||||||
|
*/
|
||||||
|
int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Import X from unsigned binary data, big endian
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param buf Input buffer
|
||||||
|
* \param buflen Input buffer size
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_read_binary( mpi *X, const unsigned char *buf, int buflen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Export X into unsigned binary data, big endian
|
||||||
|
*
|
||||||
|
* \param X Source MPI
|
||||||
|
* \param buf Output buffer
|
||||||
|
* \param buflen Output buffer size
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
|
||||||
|
*/
|
||||||
|
int mpi_write_binary( const mpi *X, unsigned char *buf, int buflen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Left-shift: X <<= count
|
||||||
|
*
|
||||||
|
* \param X MPI to shift
|
||||||
|
* \param count Amount to shift
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_shift_l( mpi *X, int count );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Right-shift: X >>= count
|
||||||
|
*
|
||||||
|
* \param X MPI to shift
|
||||||
|
* \param count Amount to shift
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_shift_r( mpi *X, int count );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Compare unsigned values
|
||||||
|
*
|
||||||
|
* \param X Left-hand MPI
|
||||||
|
* \param Y Right-hand MPI
|
||||||
|
*
|
||||||
|
* \return 1 if |X| is greater than |Y|,
|
||||||
|
* -1 if |X| is lesser than |Y| or
|
||||||
|
* 0 if |X| is equal to |Y|
|
||||||
|
*/
|
||||||
|
int mpi_cmp_abs( const mpi *X, const mpi *Y );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Compare signed values
|
||||||
|
*
|
||||||
|
* \param X Left-hand MPI
|
||||||
|
* \param Y Right-hand MPI
|
||||||
|
*
|
||||||
|
* \return 1 if X is greater than Y,
|
||||||
|
* -1 if X is lesser than Y or
|
||||||
|
* 0 if X is equal to Y
|
||||||
|
*/
|
||||||
|
int mpi_cmp_mpi( const mpi *X, const mpi *Y );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Compare signed values
|
||||||
|
*
|
||||||
|
* \param X Left-hand MPI
|
||||||
|
* \param z The integer value to compare to
|
||||||
|
*
|
||||||
|
* \return 1 if X is greater than z,
|
||||||
|
* -1 if X is lesser than z or
|
||||||
|
* 0 if X is equal to z
|
||||||
|
*/
|
||||||
|
int mpi_cmp_int( const mpi *X, int z );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Unsigned addition: X = |A| + |B|
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param B Right-hand MPI
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Unsigned substraction: X = |A| - |B|
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param B Right-hand MPI
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
|
||||||
|
*/
|
||||||
|
int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Signed addition: X = A + B
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param B Right-hand MPI
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Signed substraction: X = A - B
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param B Right-hand MPI
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Signed addition: X = A + b
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param b The integer value to add
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_add_int( mpi *X, const mpi *A, int b );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Signed substraction: X = A - b
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param b The integer value to subtract
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_sub_int( mpi *X, const mpi *A, int b );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Baseline multiplication: X = A * B
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param B Right-hand MPI
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Baseline multiplication: X = A * b
|
||||||
|
* Note: b is an unsigned integer type, thus
|
||||||
|
* Negative values of b are ignored.
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param b The integer value to multiply with
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_mul_int( mpi *X, const mpi *A, t_int b );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Division by mpi: A = Q * B + R
|
||||||
|
*
|
||||||
|
* \param Q Destination MPI for the quotient
|
||||||
|
* \param R Destination MPI for the rest value
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param B Right-hand MPI
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed,
|
||||||
|
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
|
||||||
|
*
|
||||||
|
* \note Either Q or R can be NULL.
|
||||||
|
*/
|
||||||
|
int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Division by int: A = Q * b + R
|
||||||
|
*
|
||||||
|
* \param Q Destination MPI for the quotient
|
||||||
|
* \param R Destination MPI for the rest value
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param b Integer to divide by
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed,
|
||||||
|
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
|
||||||
|
*
|
||||||
|
* \note Either Q or R can be NULL.
|
||||||
|
*/
|
||||||
|
int mpi_div_int( mpi *Q, mpi *R, const mpi *A, int b );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Modulo: R = A mod B
|
||||||
|
*
|
||||||
|
* \param R Destination MPI for the rest value
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param B Right-hand MPI
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed,
|
||||||
|
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
|
||||||
|
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
|
||||||
|
*/
|
||||||
|
int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Modulo: r = A mod b
|
||||||
|
*
|
||||||
|
* \param r Destination t_int
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param b Integer to divide by
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed,
|
||||||
|
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
|
||||||
|
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
|
||||||
|
*/
|
||||||
|
int mpi_mod_int( t_int *r, const mpi *A, int b );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sliding-window exponentiation: X = A^E mod N
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param E Exponent MPI
|
||||||
|
* \param N Modular MPI
|
||||||
|
* \param _RR Speed-up MPI used for recalculations
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed,
|
||||||
|
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
|
||||||
|
*
|
||||||
|
* \note _RR is used to avoid re-computing R*R mod N across
|
||||||
|
* multiple calls, which speeds up things a bit. It can
|
||||||
|
* be set to NULL if the extra performance is unneeded.
|
||||||
|
*/
|
||||||
|
int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Greatest common divisor: G = gcd(A, B)
|
||||||
|
*
|
||||||
|
* \param G Destination MPI
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param B Right-hand MPI
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed
|
||||||
|
*/
|
||||||
|
int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Modular inverse: X = A^-1 mod N
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param A Left-hand MPI
|
||||||
|
* \param N Right-hand MPI
|
||||||
|
*
|
||||||
|
* \return 0 if successful,
|
||||||
|
* 1 if memory allocation failed,
|
||||||
|
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
|
||||||
|
POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
|
||||||
|
*/
|
||||||
|
int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Miller-Rabin primality test
|
||||||
|
*
|
||||||
|
* \param X MPI to check
|
||||||
|
* \param f_rng RNG function
|
||||||
|
* \param p_rng RNG parameter
|
||||||
|
*
|
||||||
|
* \return 0 if successful (probably prime),
|
||||||
|
* 1 if memory allocation failed,
|
||||||
|
* POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
|
||||||
|
*/
|
||||||
|
int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Prime number generation
|
||||||
|
*
|
||||||
|
* \param X Destination MPI
|
||||||
|
* \param nbits Required size of X in bits
|
||||||
|
* \param dh_flag If 1, then (X-1)/2 will be prime too
|
||||||
|
* \param f_rng RNG function
|
||||||
|
* \param p_rng RNG parameter
|
||||||
|
*
|
||||||
|
* \return 0 if successful (probably prime),
|
||||||
|
* 1 if memory allocation failed,
|
||||||
|
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
|
||||||
|
*/
|
||||||
|
int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
|
||||||
|
int (*f_rng)(void *), void *p_rng );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checkup routine
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or 1 if the test failed
|
||||||
|
*/
|
||||||
|
int mpi_self_test( int verbose );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* bignum.h */
|
736
externals/ctrtool/polarssl/bn_mul.h
vendored
Normal file
736
externals/ctrtool/polarssl/bn_mul.h
vendored
Normal file
@ -0,0 +1,736 @@
|
|||||||
|
/**
|
||||||
|
* \file bn_mul.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2010, Brainspark B.V.
|
||||||
|
*
|
||||||
|
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||||
|
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Multiply source vector [s] with b, add result
|
||||||
|
* to destination vector [d] and set carry c.
|
||||||
|
*
|
||||||
|
* Currently supports:
|
||||||
|
*
|
||||||
|
* . IA-32 (386+) . AMD64 / EM64T
|
||||||
|
* . IA-32 (SSE2) . Motorola 68000
|
||||||
|
* . PowerPC, 32-bit . MicroBlaze
|
||||||
|
* . PowerPC, 64-bit . TriCore
|
||||||
|
* . SPARC v8 . ARM v3+
|
||||||
|
* . Alpha . MIPS32
|
||||||
|
* . C, longlong . C, generic
|
||||||
|
*/
|
||||||
|
#ifndef POLARSSL_BN_MUL_H
|
||||||
|
#define POLARSSL_BN_MUL_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined(POLARSSL_HAVE_ASM)
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#if defined(__i386__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( " \
|
||||||
|
movl %%ebx, %0; \
|
||||||
|
movl %5, %%esi; \
|
||||||
|
movl %6, %%edi; \
|
||||||
|
movl %7, %%ecx; \
|
||||||
|
movl %8, %%ebx; \
|
||||||
|
"
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
" \
|
||||||
|
lodsl; \
|
||||||
|
mull %%ebx; \
|
||||||
|
addl %%ecx, %%eax; \
|
||||||
|
adcl $0, %%edx; \
|
||||||
|
addl (%%edi), %%eax; \
|
||||||
|
adcl $0, %%edx; \
|
||||||
|
movl %%edx, %%ecx; \
|
||||||
|
stosl; \
|
||||||
|
"
|
||||||
|
|
||||||
|
#if defined(POLARSSL_HAVE_SSE2)
|
||||||
|
|
||||||
|
#define MULADDC_HUIT \
|
||||||
|
" \
|
||||||
|
movd %%ecx, %%mm1; \
|
||||||
|
movd %%ebx, %%mm0; \
|
||||||
|
movd (%%edi), %%mm3; \
|
||||||
|
paddq %%mm3, %%mm1; \
|
||||||
|
movd (%%esi), %%mm2; \
|
||||||
|
pmuludq %%mm0, %%mm2; \
|
||||||
|
movd 4(%%esi), %%mm4; \
|
||||||
|
pmuludq %%mm0, %%mm4; \
|
||||||
|
movd 8(%%esi), %%mm6; \
|
||||||
|
pmuludq %%mm0, %%mm6; \
|
||||||
|
movd 12(%%esi), %%mm7; \
|
||||||
|
pmuludq %%mm0, %%mm7; \
|
||||||
|
paddq %%mm2, %%mm1; \
|
||||||
|
movd 4(%%edi), %%mm3; \
|
||||||
|
paddq %%mm4, %%mm3; \
|
||||||
|
movd 8(%%edi), %%mm5; \
|
||||||
|
paddq %%mm6, %%mm5; \
|
||||||
|
movd 12(%%edi), %%mm4; \
|
||||||
|
paddq %%mm4, %%mm7; \
|
||||||
|
movd %%mm1, (%%edi); \
|
||||||
|
movd 16(%%esi), %%mm2; \
|
||||||
|
pmuludq %%mm0, %%mm2; \
|
||||||
|
psrlq $32, %%mm1; \
|
||||||
|
movd 20(%%esi), %%mm4; \
|
||||||
|
pmuludq %%mm0, %%mm4; \
|
||||||
|
paddq %%mm3, %%mm1; \
|
||||||
|
movd 24(%%esi), %%mm6; \
|
||||||
|
pmuludq %%mm0, %%mm6; \
|
||||||
|
movd %%mm1, 4(%%edi); \
|
||||||
|
psrlq $32, %%mm1; \
|
||||||
|
movd 28(%%esi), %%mm3; \
|
||||||
|
pmuludq %%mm0, %%mm3; \
|
||||||
|
paddq %%mm5, %%mm1; \
|
||||||
|
movd 16(%%edi), %%mm5; \
|
||||||
|
paddq %%mm5, %%mm2; \
|
||||||
|
movd %%mm1, 8(%%edi); \
|
||||||
|
psrlq $32, %%mm1; \
|
||||||
|
paddq %%mm7, %%mm1; \
|
||||||
|
movd 20(%%edi), %%mm5; \
|
||||||
|
paddq %%mm5, %%mm4; \
|
||||||
|
movd %%mm1, 12(%%edi); \
|
||||||
|
psrlq $32, %%mm1; \
|
||||||
|
paddq %%mm2, %%mm1; \
|
||||||
|
movd 24(%%edi), %%mm5; \
|
||||||
|
paddq %%mm5, %%mm6; \
|
||||||
|
movd %%mm1, 16(%%edi); \
|
||||||
|
psrlq $32, %%mm1; \
|
||||||
|
paddq %%mm4, %%mm1; \
|
||||||
|
movd 28(%%edi), %%mm5; \
|
||||||
|
paddq %%mm5, %%mm3; \
|
||||||
|
movd %%mm1, 20(%%edi); \
|
||||||
|
psrlq $32, %%mm1; \
|
||||||
|
paddq %%mm6, %%mm1; \
|
||||||
|
movd %%mm1, 24(%%edi); \
|
||||||
|
psrlq $32, %%mm1; \
|
||||||
|
paddq %%mm3, %%mm1; \
|
||||||
|
movd %%mm1, 28(%%edi); \
|
||||||
|
addl $32, %%edi; \
|
||||||
|
addl $32, %%esi; \
|
||||||
|
psrlq $32, %%mm1; \
|
||||||
|
movd %%mm1, %%ecx; \
|
||||||
|
"
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
" \
|
||||||
|
emms; \
|
||||||
|
movl %4, %%ebx; \
|
||||||
|
movl %%ecx, %1; \
|
||||||
|
movl %%edi, %2; \
|
||||||
|
movl %%esi, %3; \
|
||||||
|
" \
|
||||||
|
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
|
||||||
|
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
|
||||||
|
: "eax", "ecx", "edx", "esi", "edi" \
|
||||||
|
);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
" \
|
||||||
|
movl %4, %%ebx; \
|
||||||
|
movl %%ecx, %1; \
|
||||||
|
movl %%edi, %2; \
|
||||||
|
movl %%esi, %3; \
|
||||||
|
" \
|
||||||
|
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
|
||||||
|
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
|
||||||
|
: "eax", "ecx", "edx", "esi", "edi" \
|
||||||
|
);
|
||||||
|
#endif /* SSE2 */
|
||||||
|
#endif /* i386 */
|
||||||
|
|
||||||
|
#if defined(__amd64__) || defined (__x86_64__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "movq %0, %%rsi " :: "m" (s)); \
|
||||||
|
asm( "movq %0, %%rdi " :: "m" (d)); \
|
||||||
|
asm( "movq %0, %%rcx " :: "m" (c)); \
|
||||||
|
asm( "movq %0, %%rbx " :: "m" (b)); \
|
||||||
|
asm( "xorq %r8, %r8 " );
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "movq (%rsi),%rax " ); \
|
||||||
|
asm( "mulq %rbx " ); \
|
||||||
|
asm( "addq $8, %rsi " ); \
|
||||||
|
asm( "addq %rcx, %rax " ); \
|
||||||
|
asm( "movq %r8, %rcx " ); \
|
||||||
|
asm( "adcq $0, %rdx " ); \
|
||||||
|
asm( "nop " ); \
|
||||||
|
asm( "addq %rax, (%rdi) " ); \
|
||||||
|
asm( "adcq %rdx, %rcx " ); \
|
||||||
|
asm( "addq $8, %rdi " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "movq %%rcx, %0 " : "=m" (c)); \
|
||||||
|
asm( "movq %%rdi, %0 " : "=m" (d)); \
|
||||||
|
asm( "movq %%rsi, %0 " : "=m" (s) :: \
|
||||||
|
"rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
|
||||||
|
|
||||||
|
#endif /* AMD64 */
|
||||||
|
|
||||||
|
#if defined(__mc68020__) || defined(__mcpu32__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "movl %0, %%a2 " :: "m" (s)); \
|
||||||
|
asm( "movl %0, %%a3 " :: "m" (d)); \
|
||||||
|
asm( "movl %0, %%d3 " :: "m" (c)); \
|
||||||
|
asm( "movl %0, %%d2 " :: "m" (b)); \
|
||||||
|
asm( "moveq #0, %d0 " );
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "movel %a2@+, %d1 " ); \
|
||||||
|
asm( "mulul %d2, %d4:%d1 " ); \
|
||||||
|
asm( "addl %d3, %d1 " ); \
|
||||||
|
asm( "addxl %d0, %d4 " ); \
|
||||||
|
asm( "moveq #0, %d3 " ); \
|
||||||
|
asm( "addl %d1, %a3@+ " ); \
|
||||||
|
asm( "addxl %d4, %d3 " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "movl %%d3, %0 " : "=m" (c)); \
|
||||||
|
asm( "movl %%a3, %0 " : "=m" (d)); \
|
||||||
|
asm( "movl %%a2, %0 " : "=m" (s) :: \
|
||||||
|
"d0", "d1", "d2", "d3", "d4", "a2", "a3" );
|
||||||
|
|
||||||
|
#define MULADDC_HUIT \
|
||||||
|
asm( "movel %a2@+, %d1 " ); \
|
||||||
|
asm( "mulul %d2, %d4:%d1 " ); \
|
||||||
|
asm( "addxl %d3, %d1 " ); \
|
||||||
|
asm( "addxl %d0, %d4 " ); \
|
||||||
|
asm( "addl %d1, %a3@+ " ); \
|
||||||
|
asm( "movel %a2@+, %d1 " ); \
|
||||||
|
asm( "mulul %d2, %d3:%d1 " ); \
|
||||||
|
asm( "addxl %d4, %d1 " ); \
|
||||||
|
asm( "addxl %d0, %d3 " ); \
|
||||||
|
asm( "addl %d1, %a3@+ " ); \
|
||||||
|
asm( "movel %a2@+, %d1 " ); \
|
||||||
|
asm( "mulul %d2, %d4:%d1 " ); \
|
||||||
|
asm( "addxl %d3, %d1 " ); \
|
||||||
|
asm( "addxl %d0, %d4 " ); \
|
||||||
|
asm( "addl %d1, %a3@+ " ); \
|
||||||
|
asm( "movel %a2@+, %d1 " ); \
|
||||||
|
asm( "mulul %d2, %d3:%d1 " ); \
|
||||||
|
asm( "addxl %d4, %d1 " ); \
|
||||||
|
asm( "addxl %d0, %d3 " ); \
|
||||||
|
asm( "addl %d1, %a3@+ " ); \
|
||||||
|
asm( "movel %a2@+, %d1 " ); \
|
||||||
|
asm( "mulul %d2, %d4:%d1 " ); \
|
||||||
|
asm( "addxl %d3, %d1 " ); \
|
||||||
|
asm( "addxl %d0, %d4 " ); \
|
||||||
|
asm( "addl %d1, %a3@+ " ); \
|
||||||
|
asm( "movel %a2@+, %d1 " ); \
|
||||||
|
asm( "mulul %d2, %d3:%d1 " ); \
|
||||||
|
asm( "addxl %d4, %d1 " ); \
|
||||||
|
asm( "addxl %d0, %d3 " ); \
|
||||||
|
asm( "addl %d1, %a3@+ " ); \
|
||||||
|
asm( "movel %a2@+, %d1 " ); \
|
||||||
|
asm( "mulul %d2, %d4:%d1 " ); \
|
||||||
|
asm( "addxl %d3, %d1 " ); \
|
||||||
|
asm( "addxl %d0, %d4 " ); \
|
||||||
|
asm( "addl %d1, %a3@+ " ); \
|
||||||
|
asm( "movel %a2@+, %d1 " ); \
|
||||||
|
asm( "mulul %d2, %d3:%d1 " ); \
|
||||||
|
asm( "addxl %d4, %d1 " ); \
|
||||||
|
asm( "addxl %d0, %d3 " ); \
|
||||||
|
asm( "addl %d1, %a3@+ " ); \
|
||||||
|
asm( "addxl %d0, %d3 " );
|
||||||
|
|
||||||
|
#endif /* MC68000 */
|
||||||
|
|
||||||
|
#if defined(__powerpc__) || defined(__ppc__)
|
||||||
|
#if defined(__powerpc64__) || defined(__ppc64__)
|
||||||
|
|
||||||
|
#if defined(__MACH__) && defined(__APPLE__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "ld r3, %0 " :: "m" (s)); \
|
||||||
|
asm( "ld r4, %0 " :: "m" (d)); \
|
||||||
|
asm( "ld r5, %0 " :: "m" (c)); \
|
||||||
|
asm( "ld r6, %0 " :: "m" (b)); \
|
||||||
|
asm( "addi r3, r3, -8 " ); \
|
||||||
|
asm( "addi r4, r4, -8 " ); \
|
||||||
|
asm( "addic r5, r5, 0 " );
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "ldu r7, 8(r3) " ); \
|
||||||
|
asm( "mulld r8, r7, r6 " ); \
|
||||||
|
asm( "mulhdu r9, r7, r6 " ); \
|
||||||
|
asm( "adde r8, r8, r5 " ); \
|
||||||
|
asm( "ld r7, 8(r4) " ); \
|
||||||
|
asm( "addze r5, r9 " ); \
|
||||||
|
asm( "addc r8, r8, r7 " ); \
|
||||||
|
asm( "stdu r8, 8(r4) " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "addze r5, r5 " ); \
|
||||||
|
asm( "addi r4, r4, 8 " ); \
|
||||||
|
asm( "addi r3, r3, 8 " ); \
|
||||||
|
asm( "std r5, %0 " : "=m" (c)); \
|
||||||
|
asm( "std r4, %0 " : "=m" (d)); \
|
||||||
|
asm( "std r3, %0 " : "=m" (s) :: \
|
||||||
|
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "ld %%r3, %0 " :: "m" (s)); \
|
||||||
|
asm( "ld %%r4, %0 " :: "m" (d)); \
|
||||||
|
asm( "ld %%r5, %0 " :: "m" (c)); \
|
||||||
|
asm( "ld %%r6, %0 " :: "m" (b)); \
|
||||||
|
asm( "addi %r3, %r3, -8 " ); \
|
||||||
|
asm( "addi %r4, %r4, -8 " ); \
|
||||||
|
asm( "addic %r5, %r5, 0 " );
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "ldu %r7, 8(%r3) " ); \
|
||||||
|
asm( "mulld %r8, %r7, %r6 " ); \
|
||||||
|
asm( "mulhdu %r9, %r7, %r6 " ); \
|
||||||
|
asm( "adde %r8, %r8, %r5 " ); \
|
||||||
|
asm( "ld %r7, 8(%r4) " ); \
|
||||||
|
asm( "addze %r5, %r9 " ); \
|
||||||
|
asm( "addc %r8, %r8, %r7 " ); \
|
||||||
|
asm( "stdu %r8, 8(%r4) " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "addze %r5, %r5 " ); \
|
||||||
|
asm( "addi %r4, %r4, 8 " ); \
|
||||||
|
asm( "addi %r3, %r3, 8 " ); \
|
||||||
|
asm( "std %%r5, %0 " : "=m" (c)); \
|
||||||
|
asm( "std %%r4, %0 " : "=m" (d)); \
|
||||||
|
asm( "std %%r3, %0 " : "=m" (s) :: \
|
||||||
|
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* PPC32 */
|
||||||
|
|
||||||
|
#if defined(__MACH__) && defined(__APPLE__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "lwz r3, %0 " :: "m" (s)); \
|
||||||
|
asm( "lwz r4, %0 " :: "m" (d)); \
|
||||||
|
asm( "lwz r5, %0 " :: "m" (c)); \
|
||||||
|
asm( "lwz r6, %0 " :: "m" (b)); \
|
||||||
|
asm( "addi r3, r3, -4 " ); \
|
||||||
|
asm( "addi r4, r4, -4 " ); \
|
||||||
|
asm( "addic r5, r5, 0 " );
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "lwzu r7, 4(r3) " ); \
|
||||||
|
asm( "mullw r8, r7, r6 " ); \
|
||||||
|
asm( "mulhwu r9, r7, r6 " ); \
|
||||||
|
asm( "adde r8, r8, r5 " ); \
|
||||||
|
asm( "lwz r7, 4(r4) " ); \
|
||||||
|
asm( "addze r5, r9 " ); \
|
||||||
|
asm( "addc r8, r8, r7 " ); \
|
||||||
|
asm( "stwu r8, 4(r4) " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "addze r5, r5 " ); \
|
||||||
|
asm( "addi r4, r4, 4 " ); \
|
||||||
|
asm( "addi r3, r3, 4 " ); \
|
||||||
|
asm( "stw r5, %0 " : "=m" (c)); \
|
||||||
|
asm( "stw r4, %0 " : "=m" (d)); \
|
||||||
|
asm( "stw r3, %0 " : "=m" (s) :: \
|
||||||
|
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "lwz %%r3, %0 " :: "m" (s)); \
|
||||||
|
asm( "lwz %%r4, %0 " :: "m" (d)); \
|
||||||
|
asm( "lwz %%r5, %0 " :: "m" (c)); \
|
||||||
|
asm( "lwz %%r6, %0 " :: "m" (b)); \
|
||||||
|
asm( "addi %r3, %r3, -4 " ); \
|
||||||
|
asm( "addi %r4, %r4, -4 " ); \
|
||||||
|
asm( "addic %r5, %r5, 0 " );
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "lwzu %r7, 4(%r3) " ); \
|
||||||
|
asm( "mullw %r8, %r7, %r6 " ); \
|
||||||
|
asm( "mulhwu %r9, %r7, %r6 " ); \
|
||||||
|
asm( "adde %r8, %r8, %r5 " ); \
|
||||||
|
asm( "lwz %r7, 4(%r4) " ); \
|
||||||
|
asm( "addze %r5, %r9 " ); \
|
||||||
|
asm( "addc %r8, %r8, %r7 " ); \
|
||||||
|
asm( "stwu %r8, 4(%r4) " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "addze %r5, %r5 " ); \
|
||||||
|
asm( "addi %r4, %r4, 4 " ); \
|
||||||
|
asm( "addi %r3, %r3, 4 " ); \
|
||||||
|
asm( "stw %%r5, %0 " : "=m" (c)); \
|
||||||
|
asm( "stw %%r4, %0 " : "=m" (d)); \
|
||||||
|
asm( "stw %%r3, %0 " : "=m" (s) :: \
|
||||||
|
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PPC32 */
|
||||||
|
#endif /* PPC64 */
|
||||||
|
|
||||||
|
#if defined(__sparc__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "ld %0, %%o0 " :: "m" (s)); \
|
||||||
|
asm( "ld %0, %%o1 " :: "m" (d)); \
|
||||||
|
asm( "ld %0, %%o2 " :: "m" (c)); \
|
||||||
|
asm( "ld %0, %%o3 " :: "m" (b));
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "ld [%o0], %o4 " ); \
|
||||||
|
asm( "inc 4, %o0 " ); \
|
||||||
|
asm( "ld [%o1], %o5 " ); \
|
||||||
|
asm( "umul %o3, %o4, %o4 " ); \
|
||||||
|
asm( "addcc %o4, %o2, %o4 " ); \
|
||||||
|
asm( "rd %y, %g1 " ); \
|
||||||
|
asm( "addx %g1, 0, %g1 " ); \
|
||||||
|
asm( "addcc %o4, %o5, %o4 " ); \
|
||||||
|
asm( "st %o4, [%o1] " ); \
|
||||||
|
asm( "addx %g1, 0, %o2 " ); \
|
||||||
|
asm( "inc 4, %o1 " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "st %%o2, %0 " : "=m" (c)); \
|
||||||
|
asm( "st %%o1, %0 " : "=m" (d)); \
|
||||||
|
asm( "st %%o0, %0 " : "=m" (s) :: \
|
||||||
|
"g1", "o0", "o1", "o2", "o3", "o4", "o5" );
|
||||||
|
|
||||||
|
#endif /* SPARCv8 */
|
||||||
|
|
||||||
|
#if defined(__microblaze__) || defined(microblaze)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "lwi r3, %0 " :: "m" (s)); \
|
||||||
|
asm( "lwi r4, %0 " :: "m" (d)); \
|
||||||
|
asm( "lwi r5, %0 " :: "m" (c)); \
|
||||||
|
asm( "lwi r6, %0 " :: "m" (b)); \
|
||||||
|
asm( "andi r7, r6, 0xffff" ); \
|
||||||
|
asm( "bsrli r6, r6, 16 " );
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "lhui r8, r3, 0 " ); \
|
||||||
|
asm( "addi r3, r3, 2 " ); \
|
||||||
|
asm( "lhui r9, r3, 0 " ); \
|
||||||
|
asm( "addi r3, r3, 2 " ); \
|
||||||
|
asm( "mul r10, r9, r6 " ); \
|
||||||
|
asm( "mul r11, r8, r7 " ); \
|
||||||
|
asm( "mul r12, r9, r7 " ); \
|
||||||
|
asm( "mul r13, r8, r6 " ); \
|
||||||
|
asm( "bsrli r8, r10, 16 " ); \
|
||||||
|
asm( "bsrli r9, r11, 16 " ); \
|
||||||
|
asm( "add r13, r13, r8 " ); \
|
||||||
|
asm( "add r13, r13, r9 " ); \
|
||||||
|
asm( "bslli r10, r10, 16 " ); \
|
||||||
|
asm( "bslli r11, r11, 16 " ); \
|
||||||
|
asm( "add r12, r12, r10 " ); \
|
||||||
|
asm( "addc r13, r13, r0 " ); \
|
||||||
|
asm( "add r12, r12, r11 " ); \
|
||||||
|
asm( "addc r13, r13, r0 " ); \
|
||||||
|
asm( "lwi r10, r4, 0 " ); \
|
||||||
|
asm( "add r12, r12, r10 " ); \
|
||||||
|
asm( "addc r13, r13, r0 " ); \
|
||||||
|
asm( "add r12, r12, r5 " ); \
|
||||||
|
asm( "addc r5, r13, r0 " ); \
|
||||||
|
asm( "swi r12, r4, 0 " ); \
|
||||||
|
asm( "addi r4, r4, 4 " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "swi r5, %0 " : "=m" (c)); \
|
||||||
|
asm( "swi r4, %0 " : "=m" (d)); \
|
||||||
|
asm( "swi r3, %0 " : "=m" (s) :: \
|
||||||
|
"r3", "r4" , "r5" , "r6" , "r7" , "r8" , \
|
||||||
|
"r9", "r10", "r11", "r12", "r13" );
|
||||||
|
|
||||||
|
#endif /* MicroBlaze */
|
||||||
|
|
||||||
|
#if defined(__tricore__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "ld.a %%a2, %0 " :: "m" (s)); \
|
||||||
|
asm( "ld.a %%a3, %0 " :: "m" (d)); \
|
||||||
|
asm( "ld.w %%d4, %0 " :: "m" (c)); \
|
||||||
|
asm( "ld.w %%d1, %0 " :: "m" (b)); \
|
||||||
|
asm( "xor %d5, %d5 " );
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "ld.w %d0, [%a2+] " ); \
|
||||||
|
asm( "madd.u %e2, %e4, %d0, %d1 " ); \
|
||||||
|
asm( "ld.w %d0, [%a3] " ); \
|
||||||
|
asm( "addx %d2, %d2, %d0 " ); \
|
||||||
|
asm( "addc %d3, %d3, 0 " ); \
|
||||||
|
asm( "mov %d4, %d3 " ); \
|
||||||
|
asm( "st.w [%a3+], %d2 " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "st.w %0, %%d4 " : "=m" (c)); \
|
||||||
|
asm( "st.a %0, %%a3 " : "=m" (d)); \
|
||||||
|
asm( "st.a %0, %%a2 " : "=m" (s) :: \
|
||||||
|
"d0", "d1", "e2", "d4", "a2", "a3" );
|
||||||
|
|
||||||
|
#endif /* TriCore */
|
||||||
|
|
||||||
|
#if defined(__arm__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "ldr r0, %0 " :: "m" (s)); \
|
||||||
|
asm( "ldr r1, %0 " :: "m" (d)); \
|
||||||
|
asm( "ldr r2, %0 " :: "m" (c)); \
|
||||||
|
asm( "ldr r3, %0 " :: "m" (b));
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "ldr r4, [r0], #4 " ); \
|
||||||
|
asm( "mov r5, #0 " ); \
|
||||||
|
asm( "ldr r6, [r1] " ); \
|
||||||
|
asm( "umlal r2, r5, r3, r4 " ); \
|
||||||
|
asm( "adds r7, r6, r2 " ); \
|
||||||
|
asm( "adc r2, r5, #0 " ); \
|
||||||
|
asm( "str r7, [r1], #4 " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "str r2, %0 " : "=m" (c)); \
|
||||||
|
asm( "str r1, %0 " : "=m" (d)); \
|
||||||
|
asm( "str r0, %0 " : "=m" (s) :: \
|
||||||
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
|
||||||
|
|
||||||
|
#endif /* ARMv3 */
|
||||||
|
|
||||||
|
#if defined(__alpha__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "ldq $1, %0 " :: "m" (s)); \
|
||||||
|
asm( "ldq $2, %0 " :: "m" (d)); \
|
||||||
|
asm( "ldq $3, %0 " :: "m" (c)); \
|
||||||
|
asm( "ldq $4, %0 " :: "m" (b));
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "ldq $6, 0($1) " ); \
|
||||||
|
asm( "addq $1, 8, $1 " ); \
|
||||||
|
asm( "mulq $6, $4, $7 " ); \
|
||||||
|
asm( "umulh $6, $4, $6 " ); \
|
||||||
|
asm( "addq $7, $3, $7 " ); \
|
||||||
|
asm( "cmpult $7, $3, $3 " ); \
|
||||||
|
asm( "ldq $5, 0($2) " ); \
|
||||||
|
asm( "addq $7, $5, $7 " ); \
|
||||||
|
asm( "cmpult $7, $5, $5 " ); \
|
||||||
|
asm( "stq $7, 0($2) " ); \
|
||||||
|
asm( "addq $2, 8, $2 " ); \
|
||||||
|
asm( "addq $6, $3, $3 " ); \
|
||||||
|
asm( "addq $5, $3, $3 " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "stq $3, %0 " : "=m" (c)); \
|
||||||
|
asm( "stq $2, %0 " : "=m" (d)); \
|
||||||
|
asm( "stq $1, %0 " : "=m" (s) :: \
|
||||||
|
"$1", "$2", "$3", "$4", "$5", "$6", "$7" );
|
||||||
|
|
||||||
|
#endif /* Alpha */
|
||||||
|
|
||||||
|
#if defined(__mips__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
asm( "lw $10, %0 " :: "m" (s)); \
|
||||||
|
asm( "lw $11, %0 " :: "m" (d)); \
|
||||||
|
asm( "lw $12, %0 " :: "m" (c)); \
|
||||||
|
asm( "lw $13, %0 " :: "m" (b));
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
asm( "lw $14, 0($10) " ); \
|
||||||
|
asm( "multu $13, $14 " ); \
|
||||||
|
asm( "addi $10, $10, 4 " ); \
|
||||||
|
asm( "mflo $14 " ); \
|
||||||
|
asm( "mfhi $9 " ); \
|
||||||
|
asm( "addu $14, $12, $14 " ); \
|
||||||
|
asm( "lw $15, 0($11) " ); \
|
||||||
|
asm( "sltu $12, $14, $12 " ); \
|
||||||
|
asm( "addu $15, $14, $15 " ); \
|
||||||
|
asm( "sltu $14, $15, $14 " ); \
|
||||||
|
asm( "addu $12, $12, $9 " ); \
|
||||||
|
asm( "sw $15, 0($11) " ); \
|
||||||
|
asm( "addu $12, $12, $14 " ); \
|
||||||
|
asm( "addi $11, $11, 4 " );
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
asm( "sw $12, %0 " : "=m" (c)); \
|
||||||
|
asm( "sw $11, %0 " : "=m" (d)); \
|
||||||
|
asm( "sw $10, %0 " : "=m" (s) :: \
|
||||||
|
"$9", "$10", "$11", "$12", "$13", "$14", "$15" );
|
||||||
|
|
||||||
|
#endif /* MIPS */
|
||||||
|
#endif /* GNUC */
|
||||||
|
|
||||||
|
#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
__asm mov esi, s \
|
||||||
|
__asm mov edi, d \
|
||||||
|
__asm mov ecx, c \
|
||||||
|
__asm mov ebx, b
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
__asm lodsd \
|
||||||
|
__asm mul ebx \
|
||||||
|
__asm add eax, ecx \
|
||||||
|
__asm adc edx, 0 \
|
||||||
|
__asm add eax, [edi] \
|
||||||
|
__asm adc edx, 0 \
|
||||||
|
__asm mov ecx, edx \
|
||||||
|
__asm stosd
|
||||||
|
|
||||||
|
#if defined(POLARSSL_HAVE_SSE2)
|
||||||
|
|
||||||
|
#define EMIT __asm _emit
|
||||||
|
|
||||||
|
#define MULADDC_HUIT \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x1F \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x16 \
|
||||||
|
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
|
||||||
|
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
|
||||||
|
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
|
||||||
|
EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
|
||||||
|
EMIT 0x0F EMIT 0x7E EMIT 0x0F \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
|
||||||
|
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
|
||||||
|
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
|
||||||
|
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
|
||||||
|
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
|
||||||
|
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
|
||||||
|
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
|
||||||
|
EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
|
||||||
|
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
|
||||||
|
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
|
||||||
|
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
|
||||||
|
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
|
||||||
|
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
|
||||||
|
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
|
||||||
|
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
|
||||||
|
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
|
||||||
|
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
|
||||||
|
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
|
||||||
|
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||||
|
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
|
||||||
|
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
|
||||||
|
EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
|
||||||
|
EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
|
||||||
|
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
|
||||||
|
EMIT 0x0F EMIT 0x7E EMIT 0xC9
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
EMIT 0x0F EMIT 0x77 \
|
||||||
|
__asm mov c, ecx \
|
||||||
|
__asm mov d, edi \
|
||||||
|
__asm mov s, esi \
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
__asm mov c, ecx \
|
||||||
|
__asm mov d, edi \
|
||||||
|
__asm mov s, esi \
|
||||||
|
|
||||||
|
#endif /* SSE2 */
|
||||||
|
#endif /* MSVC */
|
||||||
|
|
||||||
|
#endif /* POLARSSL_HAVE_ASM */
|
||||||
|
|
||||||
|
#if !defined(MULADDC_CORE)
|
||||||
|
#if defined(POLARSSL_HAVE_LONGLONG)
|
||||||
|
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
{ \
|
||||||
|
t_dbl r; \
|
||||||
|
t_int r0, r1;
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
r = *(s++) * (t_dbl) b; \
|
||||||
|
r0 = r; \
|
||||||
|
r1 = r >> biL; \
|
||||||
|
r0 += c; r1 += (r0 < c); \
|
||||||
|
r0 += *d; r1 += (r0 < *d); \
|
||||||
|
c = r1; *(d++) = r0;
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define MULADDC_INIT \
|
||||||
|
{ \
|
||||||
|
t_int s0, s1, b0, b1; \
|
||||||
|
t_int r0, r1, rx, ry; \
|
||||||
|
b0 = ( b << biH ) >> biH; \
|
||||||
|
b1 = ( b >> biH );
|
||||||
|
|
||||||
|
#define MULADDC_CORE \
|
||||||
|
s0 = ( *s << biH ) >> biH; \
|
||||||
|
s1 = ( *s >> biH ); s++; \
|
||||||
|
rx = s0 * b1; r0 = s0 * b0; \
|
||||||
|
ry = s1 * b0; r1 = s1 * b1; \
|
||||||
|
r1 += ( rx >> biH ); \
|
||||||
|
r1 += ( ry >> biH ); \
|
||||||
|
rx <<= biH; ry <<= biH; \
|
||||||
|
r0 += rx; r1 += (r0 < rx); \
|
||||||
|
r0 += ry; r1 += (r0 < ry); \
|
||||||
|
r0 += c; r1 += (r0 < c); \
|
||||||
|
r0 += *d; r1 += (r0 < *d); \
|
||||||
|
c = r1; *(d++) = r0;
|
||||||
|
|
||||||
|
#define MULADDC_STOP \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* C (generic) */
|
||||||
|
#endif /* C (longlong) */
|
||||||
|
|
||||||
|
#endif /* bn_mul.h */
|
336
externals/ctrtool/polarssl/config.h
vendored
Normal file
336
externals/ctrtool/polarssl/config.h
vendored
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
/**
|
||||||
|
* \file config.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2010, Brainspark B.V.
|
||||||
|
*
|
||||||
|
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||||
|
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* This set of compile-time options may be used to enable
|
||||||
|
* or disable features selectively, and reduce the global
|
||||||
|
* memory footprint.
|
||||||
|
*/
|
||||||
|
#ifndef POLARSSL_CONFIG_H
|
||||||
|
#define POLARSSL_CONFIG_H
|
||||||
|
|
||||||
|
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||||
|
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment if native integers are 8-bit wide.
|
||||||
|
*
|
||||||
|
#define POLARSSL_HAVE_INT8
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment if native integers are 16-bit wide.
|
||||||
|
*
|
||||||
|
#define POLARSSL_HAVE_INT16
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment if the compiler supports long long.
|
||||||
|
*
|
||||||
|
#define POLARSSL_HAVE_LONGLONG
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment to enable the use of assembly code.
|
||||||
|
*
|
||||||
|
* Requires support for asm() in compiler.
|
||||||
|
*
|
||||||
|
* Used in:
|
||||||
|
* library/timing.c
|
||||||
|
* library/padlock.c
|
||||||
|
* include/polarssl/bn_mul.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//#define POLARSSL_HAVE_ASM
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment if the CPU supports SSE2 (IA-32 specific).
|
||||||
|
*
|
||||||
|
#define POLARSSL_HAVE_SSE2
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable all SSL/TLS debugging messages.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_DEBUG_MSG
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable the checkup functions (*_self_test).
|
||||||
|
*/
|
||||||
|
//#define POLARSSL_SELF_TEST
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable run-time version information functions
|
||||||
|
*/
|
||||||
|
#define POLARSSL_VERSION_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable the prime-number generation code.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_GENPRIME
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uncomment this macro to store the AES tables in ROM.
|
||||||
|
*
|
||||||
|
#define POLARSSL_AES_ROM_TABLES
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/aes.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites:
|
||||||
|
* SSL_RSA_AES_128_SHA
|
||||||
|
* SSL_RSA_AES_256_SHA
|
||||||
|
* SSL_EDH_RSA_AES_256_SHA
|
||||||
|
*/
|
||||||
|
#define POLARSSL_AES_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/arc4.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites:
|
||||||
|
* SSL_RSA_RC4_128_MD5
|
||||||
|
* SSL_RSA_RC4_128_SHA
|
||||||
|
*/
|
||||||
|
#define POLARSSL_ARC4_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/base64.c
|
||||||
|
* Caller: library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module is required for X.509 support.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_BASE64_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/bignum.c
|
||||||
|
* Caller: library/dhm.c
|
||||||
|
* library/rsa.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
* library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module is required for RSA and DHM support.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_BIGNUM_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/camellia.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module enabled the following cipher suites:
|
||||||
|
* SSL_RSA_CAMELLIA_128_SHA
|
||||||
|
* SSL_RSA_CAMELLIA_256_SHA
|
||||||
|
* SSL_EDH_RSA_CAMELLIA_256_SHA
|
||||||
|
*/
|
||||||
|
#define POLARSSL_CAMELLIA_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/certs.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module is used for testing (ssl_client/server).
|
||||||
|
*/
|
||||||
|
#define POLARSSL_CERTS_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/debug.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module provides debugging functions.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_DEBUG_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/des.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites:
|
||||||
|
* SSL_RSA_DES_168_SHA
|
||||||
|
* SSL_EDH_RSA_DES_168_SHA
|
||||||
|
*/
|
||||||
|
#define POLARSSL_DES_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/dhm.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
*
|
||||||
|
* This module enables the following ciphersuites:
|
||||||
|
* SSL_EDH_RSA_DES_168_SHA
|
||||||
|
* SSL_EDH_RSA_AES_256_SHA
|
||||||
|
* SSL_EDH_RSA_CAMELLIA_256_SHA
|
||||||
|
*/
|
||||||
|
#define POLARSSL_DHM_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/havege.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module enables the HAVEGE random number generator.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_HAVEGE_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/md2.c
|
||||||
|
* Caller: library/x509parse.c
|
||||||
|
*
|
||||||
|
* Uncomment to enable support for (rare) MD2-signed X.509 certs.
|
||||||
|
*
|
||||||
|
#define POLARSSL_MD2_C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/md4.c
|
||||||
|
* Caller: library/x509parse.c
|
||||||
|
*
|
||||||
|
* Uncomment to enable support for (rare) MD4-signed X.509 certs.
|
||||||
|
*
|
||||||
|
#define POLARSSL_MD4_C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/md5.c
|
||||||
|
* Caller: library/ssl_tls.c
|
||||||
|
* library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS and X.509.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_MD5_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/net.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module provides TCP/IP networking routines.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_NET_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/padlock.c
|
||||||
|
* Caller: library/aes.c
|
||||||
|
*
|
||||||
|
* This modules adds support for the VIA PadLock on x86.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_PADLOCK_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/rsa.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
* library/x509.c
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS and MD5-signed certificates.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_RSA_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/sha1.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
* library/x509parse.c
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS and SHA1-signed certificates.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SHA1_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/sha2.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module adds support for SHA-224 and SHA-256.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SHA2_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/sha4.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module adds support for SHA-384 and SHA-512.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SHA4_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/ssl_cli.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS client support.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SSL_CLI_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/ssl_srv.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS server support.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SSL_SRV_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/ssl_tls.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
*
|
||||||
|
* This module is required for SSL/TLS.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_SSL_TLS_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/timing.c
|
||||||
|
* Caller: library/havege.c
|
||||||
|
*
|
||||||
|
* This module is used by the HAVEGE random number generator.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_TIMING_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/x509parse.c
|
||||||
|
* Caller: library/ssl_cli.c
|
||||||
|
* library/ssl_srv.c
|
||||||
|
* library/ssl_tls.c
|
||||||
|
*
|
||||||
|
* This module is required for X.509 certificate parsing.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_X509_PARSE_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/x509_write.c
|
||||||
|
* Caller:
|
||||||
|
*
|
||||||
|
* This module is required for X.509 certificate writing.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_X509_WRITE_C
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module: library/xtea.c
|
||||||
|
* Caller:
|
||||||
|
*/
|
||||||
|
#define POLARSSL_XTEA_C
|
||||||
|
|
||||||
|
#endif /* config.h */
|
98
externals/ctrtool/polarssl/padlock.h
vendored
Normal file
98
externals/ctrtool/polarssl/padlock.h
vendored
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* \file padlock.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2010, Brainspark B.V.
|
||||||
|
*
|
||||||
|
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||||
|
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
#ifndef POLARSSL_PADLOCK_H
|
||||||
|
#define POLARSSL_PADLOCK_H
|
||||||
|
|
||||||
|
#include "aes.h"
|
||||||
|
|
||||||
|
#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__i386__)
|
||||||
|
|
||||||
|
#ifndef POLARSSL_HAVE_X86
|
||||||
|
#define POLARSSL_HAVE_X86
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PADLOCK_RNG 0x000C
|
||||||
|
#define PADLOCK_ACE 0x00C0
|
||||||
|
#define PADLOCK_PHE 0x0C00
|
||||||
|
#define PADLOCK_PMM 0x3000
|
||||||
|
|
||||||
|
#define PADLOCK_ALIGN16(x) (unsigned long *) (16 + ((long) x & ~15))
|
||||||
|
|
||||||
|
#define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED -0x08E0
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief PadLock detection routine
|
||||||
|
*
|
||||||
|
* \param The feature to detect
|
||||||
|
*
|
||||||
|
* \return 1 if CPU has support for the feature, 0 otherwise
|
||||||
|
*/
|
||||||
|
int padlock_supports( int feature );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief PadLock AES-ECB block en(de)cryption
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
* \param input 16-byte input block
|
||||||
|
* \param output 16-byte output block
|
||||||
|
*
|
||||||
|
* \return 0 if success, 1 if operation failed
|
||||||
|
*/
|
||||||
|
int padlock_xcryptecb( aes_context *ctx,
|
||||||
|
int mode,
|
||||||
|
const unsigned char input[16],
|
||||||
|
unsigned char output[16] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief PadLock AES-CBC buffer en(de)cryption
|
||||||
|
*
|
||||||
|
* \param ctx AES context
|
||||||
|
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||||
|
* \param length length of the input data
|
||||||
|
* \param iv initialization vector (updated after use)
|
||||||
|
* \param input buffer holding the input data
|
||||||
|
* \param output buffer holding the output data
|
||||||
|
*
|
||||||
|
* \return 0 if success, 1 if operation failed
|
||||||
|
*/
|
||||||
|
int padlock_xcryptcbc( aes_context *ctx,
|
||||||
|
int mode,
|
||||||
|
int length,
|
||||||
|
unsigned char iv[16],
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAVE_X86 */
|
||||||
|
|
||||||
|
#endif /* padlock.h */
|
823
externals/ctrtool/polarssl/rsa.c
vendored
Normal file
823
externals/ctrtool/polarssl/rsa.c
vendored
Normal file
@ -0,0 +1,823 @@
|
|||||||
|
/*
|
||||||
|
* The RSA public-key cryptosystem
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2010, Brainspark B.V.
|
||||||
|
*
|
||||||
|
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||||
|
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
|
||||||
|
*
|
||||||
|
* http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
|
||||||
|
* http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined(POLARSSL_RSA_C)
|
||||||
|
|
||||||
|
#include "rsa.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize an RSA context
|
||||||
|
*/
|
||||||
|
void rsa_init( rsa_context *ctx,
|
||||||
|
int padding,
|
||||||
|
int hash_id )
|
||||||
|
{
|
||||||
|
memset( ctx, 0, sizeof( rsa_context ) );
|
||||||
|
|
||||||
|
ctx->padding = padding;
|
||||||
|
ctx->hash_id = hash_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(POLARSSL_GENPRIME)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate an RSA keypair
|
||||||
|
*/
|
||||||
|
int rsa_gen_key( rsa_context *ctx,
|
||||||
|
int (*f_rng)(void *),
|
||||||
|
void *p_rng,
|
||||||
|
int nbits, int exponent )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
mpi P1, Q1, H, G;
|
||||||
|
|
||||||
|
if( f_rng == NULL || nbits < 128 || exponent < 3 )
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
mpi_init( &P1, &Q1, &H, &G, NULL );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find primes P and Q with Q < P so that:
|
||||||
|
* GCD( E, (P-1)*(Q-1) ) == 1
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_lset( &ctx->E, exponent ) );
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
|
||||||
|
f_rng, p_rng ) );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
|
||||||
|
f_rng, p_rng ) );
|
||||||
|
|
||||||
|
if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
|
||||||
|
mpi_swap( &ctx->P, &ctx->Q );
|
||||||
|
|
||||||
|
if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
|
||||||
|
if( mpi_msb( &ctx->N ) != nbits )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
|
||||||
|
MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
|
||||||
|
MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
|
||||||
|
}
|
||||||
|
while( mpi_cmp_int( &G, 1 ) != 0 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* D = E^-1 mod ((P-1)*(Q-1))
|
||||||
|
* DP = D mod (P - 1)
|
||||||
|
* DQ = D mod (Q - 1)
|
||||||
|
* QP = Q^-1 mod P
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
|
||||||
|
MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
|
||||||
|
|
||||||
|
ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
mpi_free( &G, &H, &Q1, &P1, NULL );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
rsa_free( ctx );
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_GEN_FAILED | ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check a public RSA key
|
||||||
|
*/
|
||||||
|
int rsa_check_pubkey( const rsa_context *ctx )
|
||||||
|
{
|
||||||
|
if( !ctx->N.p || !ctx->E.p )
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||||
|
|
||||||
|
if( ( ctx->N.p[0] & 1 ) == 0 ||
|
||||||
|
( ctx->E.p[0] & 1 ) == 0 )
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||||
|
|
||||||
|
if( mpi_msb( &ctx->N ) < 128 ||
|
||||||
|
mpi_msb( &ctx->N ) > 4096 )
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||||
|
|
||||||
|
if( mpi_msb( &ctx->E ) < 2 ||
|
||||||
|
mpi_msb( &ctx->E ) > 64 )
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check a private RSA key
|
||||||
|
*/
|
||||||
|
int rsa_check_privkey( const rsa_context *ctx )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2;
|
||||||
|
|
||||||
|
if( ( ret = rsa_check_pubkey( ctx ) ) != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
if( !ctx->P.p || !ctx->Q.p || !ctx->D.p )
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
|
||||||
|
|
||||||
|
mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, &G2, &L1, &L2, NULL );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
|
||||||
|
MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
|
||||||
|
MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
|
||||||
|
MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) );
|
||||||
|
MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for a valid PKCS1v2 private key
|
||||||
|
*/
|
||||||
|
if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 &&
|
||||||
|
mpi_cmp_int( &L2, 0 ) == 0 &&
|
||||||
|
mpi_cmp_int( &I, 1 ) == 0 &&
|
||||||
|
mpi_cmp_int( &G, 1 ) == 0 )
|
||||||
|
{
|
||||||
|
mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
|
||||||
|
return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do an RSA public key operation
|
||||||
|
*/
|
||||||
|
int rsa_public( rsa_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output )
|
||||||
|
{
|
||||||
|
int ret, olen;
|
||||||
|
mpi T;
|
||||||
|
|
||||||
|
mpi_init( &T, NULL );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
|
||||||
|
|
||||||
|
if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
|
||||||
|
{
|
||||||
|
mpi_free( &T, NULL );
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
olen = ctx->len;
|
||||||
|
MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
|
||||||
|
MPI_CHK( mpi_write_binary( &T, output, olen ) );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
mpi_free( &T, NULL );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
return( POLARSSL_ERR_RSA_PUBLIC_FAILED | ret );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do an RSA private key operation
|
||||||
|
*/
|
||||||
|
int rsa_private( rsa_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output )
|
||||||
|
{
|
||||||
|
int ret, olen;
|
||||||
|
mpi T, T1, T2;
|
||||||
|
|
||||||
|
mpi_init( &T, &T1, &T2, NULL );
|
||||||
|
|
||||||
|
MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
|
||||||
|
|
||||||
|
if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
|
||||||
|
{
|
||||||
|
mpi_free( &T, NULL );
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* faster decryption using the CRT
|
||||||
|
*
|
||||||
|
* T1 = input ^ dP mod P
|
||||||
|
* T2 = input ^ dQ mod Q
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
|
||||||
|
MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* T = (T1 - T2) * (Q^-1 mod P) mod P
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) );
|
||||||
|
MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) );
|
||||||
|
MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output = T2 + T * Q
|
||||||
|
*/
|
||||||
|
MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
|
||||||
|
MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
olen = ctx->len;
|
||||||
|
MPI_CHK( mpi_write_binary( &T, output, olen ) );
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
mpi_free( &T, &T1, &T2, NULL );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
return( POLARSSL_ERR_RSA_PRIVATE_FAILED | ret );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the message padding, then do an RSA operation
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_encrypt( rsa_context *ctx,
|
||||||
|
int (*f_rng)(void *),
|
||||||
|
void *p_rng,
|
||||||
|
int mode, int ilen,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output )
|
||||||
|
{
|
||||||
|
int nb_pad, olen;
|
||||||
|
unsigned char *p = output;
|
||||||
|
|
||||||
|
olen = ctx->len;
|
||||||
|
|
||||||
|
switch( ctx->padding )
|
||||||
|
{
|
||||||
|
case RSA_PKCS_V15:
|
||||||
|
|
||||||
|
if( ilen < 0 || olen < ilen + 11 || f_rng == NULL )
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
nb_pad = olen - 3 - ilen;
|
||||||
|
|
||||||
|
*p++ = 0;
|
||||||
|
*p++ = RSA_CRYPT;
|
||||||
|
|
||||||
|
while( nb_pad-- > 0 )
|
||||||
|
{
|
||||||
|
int rng_dl = 100;
|
||||||
|
|
||||||
|
do {
|
||||||
|
*p = (unsigned char) f_rng( p_rng );
|
||||||
|
} while( *p == 0 && --rng_dl );
|
||||||
|
|
||||||
|
// Check if RNG failed to generate data
|
||||||
|
//
|
||||||
|
if( rng_dl == 0 )
|
||||||
|
return POLARSSL_ERR_RSA_RNG_FAILED;
|
||||||
|
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
*p++ = 0;
|
||||||
|
memcpy( p, input, ilen );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( ( mode == RSA_PUBLIC )
|
||||||
|
? rsa_public( ctx, output, output )
|
||||||
|
: rsa_private( ctx, output, output ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do an RSA operation, then remove the message padding
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||||
|
int mode, int *olen,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output,
|
||||||
|
int output_max_len)
|
||||||
|
{
|
||||||
|
int ret, ilen;
|
||||||
|
unsigned char *p;
|
||||||
|
unsigned char buf[1024];
|
||||||
|
|
||||||
|
ilen = ctx->len;
|
||||||
|
|
||||||
|
if( ilen < 16 || ilen > (int) sizeof( buf ) )
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
ret = ( mode == RSA_PUBLIC )
|
||||||
|
? rsa_public( ctx, input, buf )
|
||||||
|
: rsa_private( ctx, input, buf );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
|
||||||
|
switch( ctx->padding )
|
||||||
|
{
|
||||||
|
case RSA_PKCS_V15:
|
||||||
|
|
||||||
|
if( *p++ != 0 || *p++ != RSA_CRYPT )
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
|
||||||
|
while( *p != 0 )
|
||||||
|
{
|
||||||
|
if( p >= buf + ilen - 1 )
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ilen - (int)(p - buf) > output_max_len)
|
||||||
|
return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
|
||||||
|
|
||||||
|
*olen = ilen - (int)(p - buf);
|
||||||
|
memcpy( output, p, *olen );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do an RSA operation to sign the message digest
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_sign( rsa_context *ctx,
|
||||||
|
int mode,
|
||||||
|
int hash_id,
|
||||||
|
int hashlen,
|
||||||
|
const unsigned char *hash,
|
||||||
|
unsigned char *sig )
|
||||||
|
{
|
||||||
|
int nb_pad, olen;
|
||||||
|
unsigned char *p = sig;
|
||||||
|
|
||||||
|
olen = ctx->len;
|
||||||
|
|
||||||
|
switch( ctx->padding )
|
||||||
|
{
|
||||||
|
case RSA_PKCS_V15:
|
||||||
|
|
||||||
|
switch( hash_id )
|
||||||
|
{
|
||||||
|
case SIG_RSA_RAW:
|
||||||
|
nb_pad = olen - 3 - hashlen;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_MD2:
|
||||||
|
case SIG_RSA_MD4:
|
||||||
|
case SIG_RSA_MD5:
|
||||||
|
nb_pad = olen - 3 - 34;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA1:
|
||||||
|
nb_pad = olen - 3 - 35;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA224:
|
||||||
|
nb_pad = olen - 3 - 47;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA256:
|
||||||
|
nb_pad = olen - 3 - 51;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA384:
|
||||||
|
nb_pad = olen - 3 - 67;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA512:
|
||||||
|
nb_pad = olen - 3 - 83;
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( nb_pad < 8 )
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
*p++ = 0;
|
||||||
|
*p++ = RSA_SIGN;
|
||||||
|
memset( p, 0xFF, nb_pad );
|
||||||
|
p += nb_pad;
|
||||||
|
*p++ = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( hash_id )
|
||||||
|
{
|
||||||
|
case SIG_RSA_RAW:
|
||||||
|
memcpy( p, hash, hashlen );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_MD2:
|
||||||
|
memcpy( p, ASN1_HASH_MDX, 18 );
|
||||||
|
memcpy( p + 18, hash, 16 );
|
||||||
|
p[13] = 2; break;
|
||||||
|
|
||||||
|
case SIG_RSA_MD4:
|
||||||
|
memcpy( p, ASN1_HASH_MDX, 18 );
|
||||||
|
memcpy( p + 18, hash, 16 );
|
||||||
|
p[13] = 4; break;
|
||||||
|
|
||||||
|
case SIG_RSA_MD5:
|
||||||
|
memcpy( p, ASN1_HASH_MDX, 18 );
|
||||||
|
memcpy( p + 18, hash, 16 );
|
||||||
|
p[13] = 5; break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA1:
|
||||||
|
memcpy( p, ASN1_HASH_SHA1, 15 );
|
||||||
|
memcpy( p + 15, hash, 20 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA224:
|
||||||
|
memcpy( p, ASN1_HASH_SHA2X, 19 );
|
||||||
|
memcpy( p + 19, hash, 28 );
|
||||||
|
p[1] += 28; p[14] = 4; p[18] += 28; break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA256:
|
||||||
|
memcpy( p, ASN1_HASH_SHA2X, 19 );
|
||||||
|
memcpy( p + 19, hash, 32 );
|
||||||
|
p[1] += 32; p[14] = 1; p[18] += 32; break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA384:
|
||||||
|
memcpy( p, ASN1_HASH_SHA2X, 19 );
|
||||||
|
memcpy( p + 19, hash, 48 );
|
||||||
|
p[1] += 48; p[14] = 2; p[18] += 48; break;
|
||||||
|
|
||||||
|
case SIG_RSA_SHA512:
|
||||||
|
memcpy( p, ASN1_HASH_SHA2X, 19 );
|
||||||
|
memcpy( p + 19, hash, 64 );
|
||||||
|
p[1] += 64; p[14] = 3; p[18] += 64; break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( ( mode == RSA_PUBLIC )
|
||||||
|
? rsa_public( ctx, sig, sig )
|
||||||
|
: rsa_private( ctx, sig, sig ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do an RSA operation and check the message digest
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_verify( rsa_context *ctx,
|
||||||
|
int mode,
|
||||||
|
int hash_id,
|
||||||
|
int hashlen,
|
||||||
|
const unsigned char *hash,
|
||||||
|
unsigned char *sig )
|
||||||
|
{
|
||||||
|
int ret, len, siglen;
|
||||||
|
unsigned char *p, c;
|
||||||
|
unsigned char buf[1024];
|
||||||
|
|
||||||
|
siglen = ctx->len;
|
||||||
|
|
||||||
|
if( siglen < 16 || siglen > (int) sizeof( buf ) )
|
||||||
|
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||||
|
|
||||||
|
ret = ( mode == RSA_PUBLIC )
|
||||||
|
? rsa_public( ctx, sig, buf )
|
||||||
|
: rsa_private( ctx, sig, buf );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
return( ret );
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
|
||||||
|
switch( ctx->padding )
|
||||||
|
{
|
||||||
|
case RSA_PKCS_V15:
|
||||||
|
|
||||||
|
if( *p++ != 0 || *p++ != RSA_SIGN )
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
|
||||||
|
while( *p != 0 )
|
||||||
|
{
|
||||||
|
if( p >= buf + siglen - 1 || *p != 0xFF )
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = siglen - (int)( p - buf );
|
||||||
|
|
||||||
|
if( len == 34 )
|
||||||
|
{
|
||||||
|
c = p[13];
|
||||||
|
p[13] = 0;
|
||||||
|
|
||||||
|
if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
|
||||||
|
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||||
|
|
||||||
|
if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
|
||||||
|
( c == 4 && hash_id == SIG_RSA_MD4 ) ||
|
||||||
|
( c == 5 && hash_id == SIG_RSA_MD5 ) )
|
||||||
|
{
|
||||||
|
if( memcmp( p + 18, hash, 16 ) == 0 )
|
||||||
|
return( 0 );
|
||||||
|
else
|
||||||
|
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( len == 35 && hash_id == SIG_RSA_SHA1 )
|
||||||
|
{
|
||||||
|
if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
|
||||||
|
memcmp( p + 15, hash, 20 ) == 0 )
|
||||||
|
return( 0 );
|
||||||
|
else
|
||||||
|
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||||
|
}
|
||||||
|
if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
|
||||||
|
( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
|
||||||
|
( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
|
||||||
|
( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
|
||||||
|
{
|
||||||
|
c = p[1] - 17;
|
||||||
|
p[1] = 17;
|
||||||
|
p[14] = 0;
|
||||||
|
|
||||||
|
if( p[18] == c &&
|
||||||
|
memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
|
||||||
|
memcmp( p + 19, hash, c ) == 0 )
|
||||||
|
return( 0 );
|
||||||
|
else
|
||||||
|
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( len == hashlen && hash_id == SIG_RSA_RAW )
|
||||||
|
{
|
||||||
|
if( memcmp( p, hash, hashlen ) == 0 )
|
||||||
|
return( 0 );
|
||||||
|
else
|
||||||
|
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free the components of an RSA key
|
||||||
|
*/
|
||||||
|
void rsa_free( rsa_context *ctx )
|
||||||
|
{
|
||||||
|
mpi_free( &ctx->RQ, &ctx->RP, &ctx->RN,
|
||||||
|
&ctx->QP, &ctx->DQ, &ctx->DP,
|
||||||
|
&ctx->Q, &ctx->P, &ctx->D,
|
||||||
|
&ctx->E, &ctx->N, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SELF_TEST)
|
||||||
|
|
||||||
|
#include "polarssl/sha1.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Example RSA-1024 keypair, for test purposes
|
||||||
|
*/
|
||||||
|
#define KEY_LEN 128
|
||||||
|
|
||||||
|
#define RSA_N "9292758453063D803DD603D5E777D788" \
|
||||||
|
"8ED1D5BF35786190FA2F23EBC0848AEA" \
|
||||||
|
"DDA92CA6C3D80B32C4D109BE0F36D6AE" \
|
||||||
|
"7130B9CED7ACDF54CFC7555AC14EEBAB" \
|
||||||
|
"93A89813FBF3C4F8066D2D800F7C38A8" \
|
||||||
|
"1AE31942917403FF4946B0A83D3D3E05" \
|
||||||
|
"EE57C6F5F5606FB5D4BC6CD34EE0801A" \
|
||||||
|
"5E94BB77B07507233A0BC7BAC8F90F79"
|
||||||
|
|
||||||
|
#define RSA_E "10001"
|
||||||
|
|
||||||
|
#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
|
||||||
|
"66CA472BC44D253102F8B4A9D3BFA750" \
|
||||||
|
"91386C0077937FE33FA3252D28855837" \
|
||||||
|
"AE1B484A8A9A45F7EE8C0C634F99E8CD" \
|
||||||
|
"DF79C5CE07EE72C7F123142198164234" \
|
||||||
|
"CABB724CF78B8173B9F880FC86322407" \
|
||||||
|
"AF1FEDFDDE2BEB674CA15F3E81A1521E" \
|
||||||
|
"071513A1E85B5DFA031F21ECAE91A34D"
|
||||||
|
|
||||||
|
#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
|
||||||
|
"2C01CAD19EA484A87EA4377637E75500" \
|
||||||
|
"FCB2005C5C7DD6EC4AC023CDA285D796" \
|
||||||
|
"C3D9E75E1EFC42488BB4F1D13AC30A57"
|
||||||
|
|
||||||
|
#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
|
||||||
|
"E211C2B9E5DB1ED0BF61D0D9899620F4" \
|
||||||
|
"910E4168387E3C30AA1E00C339A79508" \
|
||||||
|
"8452DD96A9A5EA5D9DCA68DA636032AF"
|
||||||
|
|
||||||
|
#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
|
||||||
|
"3C94D22288ACD763FD8E5600ED4A702D" \
|
||||||
|
"F84198A5F06C2E72236AE490C93F07F8" \
|
||||||
|
"3CC559CD27BC2D1CA488811730BB5725"
|
||||||
|
|
||||||
|
#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
|
||||||
|
"D8AAEA56749EA28623272E4F7D0592AF" \
|
||||||
|
"7C1F1313CAC9471B5C523BFE592F517B" \
|
||||||
|
"407A1BD76C164B93DA2D32A383E58357"
|
||||||
|
|
||||||
|
#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
|
||||||
|
"F38D18D2B2F0E2DD275AA977E2BF4411" \
|
||||||
|
"F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
|
||||||
|
"A74206CEC169D74BF5A8C50D6F48EA08"
|
||||||
|
|
||||||
|
#define PT_LEN 24
|
||||||
|
#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
|
||||||
|
"\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
|
||||||
|
|
||||||
|
static int myrand( void *rng_state )
|
||||||
|
{
|
||||||
|
if( rng_state != NULL )
|
||||||
|
rng_state = NULL;
|
||||||
|
|
||||||
|
return( rand() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checkup routine
|
||||||
|
*/
|
||||||
|
int rsa_self_test( int verbose )
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
rsa_context rsa;
|
||||||
|
unsigned char sha1sum[20];
|
||||||
|
unsigned char rsa_plaintext[PT_LEN];
|
||||||
|
unsigned char rsa_decrypted[PT_LEN];
|
||||||
|
unsigned char rsa_ciphertext[KEY_LEN];
|
||||||
|
|
||||||
|
rsa_init( &rsa, RSA_PKCS_V15, 0 );
|
||||||
|
|
||||||
|
rsa.len = KEY_LEN;
|
||||||
|
mpi_read_string( &rsa.N , 16, RSA_N );
|
||||||
|
mpi_read_string( &rsa.E , 16, RSA_E );
|
||||||
|
mpi_read_string( &rsa.D , 16, RSA_D );
|
||||||
|
mpi_read_string( &rsa.P , 16, RSA_P );
|
||||||
|
mpi_read_string( &rsa.Q , 16, RSA_Q );
|
||||||
|
mpi_read_string( &rsa.DP, 16, RSA_DP );
|
||||||
|
mpi_read_string( &rsa.DQ, 16, RSA_DQ );
|
||||||
|
mpi_read_string( &rsa.QP, 16, RSA_QP );
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( " RSA key validation: " );
|
||||||
|
|
||||||
|
if( rsa_check_pubkey( &rsa ) != 0 ||
|
||||||
|
rsa_check_privkey( &rsa ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n PKCS#1 encryption : " );
|
||||||
|
|
||||||
|
memcpy( rsa_plaintext, RSA_PT, PT_LEN );
|
||||||
|
|
||||||
|
if( rsa_pkcs1_encrypt( &rsa, &myrand, NULL, RSA_PUBLIC, PT_LEN,
|
||||||
|
rsa_plaintext, rsa_ciphertext ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n PKCS#1 decryption : " );
|
||||||
|
|
||||||
|
if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len,
|
||||||
|
rsa_ciphertext, rsa_decrypted,
|
||||||
|
sizeof(rsa_decrypted) ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n PKCS#1 data sign : " );
|
||||||
|
|
||||||
|
sha1( rsa_plaintext, PT_LEN, sha1sum );
|
||||||
|
|
||||||
|
if( rsa_pkcs1_sign( &rsa, RSA_PRIVATE, SIG_RSA_SHA1, 20,
|
||||||
|
sha1sum, rsa_ciphertext ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n PKCS#1 sig. verify: " );
|
||||||
|
|
||||||
|
if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1, 20,
|
||||||
|
sha1sum, rsa_ciphertext ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n\n" );
|
||||||
|
|
||||||
|
rsa_free( &rsa );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
353
externals/ctrtool/polarssl/rsa.h
vendored
Normal file
353
externals/ctrtool/polarssl/rsa.h
vendored
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
/**
|
||||||
|
* \file rsa.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2010, Brainspark B.V.
|
||||||
|
*
|
||||||
|
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||||
|
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
#ifndef POLARSSL_RSA_H
|
||||||
|
#define POLARSSL_RSA_H
|
||||||
|
|
||||||
|
#include "bignum.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RSA Error codes
|
||||||
|
*/
|
||||||
|
#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x0400
|
||||||
|
#define POLARSSL_ERR_RSA_INVALID_PADDING -0x0410
|
||||||
|
#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x0420
|
||||||
|
#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x0430
|
||||||
|
#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440
|
||||||
|
#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450
|
||||||
|
#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460
|
||||||
|
#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x0470
|
||||||
|
#define POLARSSL_ERR_RSA_RNG_FAILED -0x0480
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PKCS#1 constants
|
||||||
|
*/
|
||||||
|
#define SIG_RSA_RAW 0
|
||||||
|
#define SIG_RSA_MD2 2
|
||||||
|
#define SIG_RSA_MD4 3
|
||||||
|
#define SIG_RSA_MD5 4
|
||||||
|
#define SIG_RSA_SHA1 5
|
||||||
|
#define SIG_RSA_SHA224 14
|
||||||
|
#define SIG_RSA_SHA256 11
|
||||||
|
#define SIG_RSA_SHA384 12
|
||||||
|
#define SIG_RSA_SHA512 13
|
||||||
|
|
||||||
|
#define RSA_PUBLIC 0
|
||||||
|
#define RSA_PRIVATE 1
|
||||||
|
|
||||||
|
#define RSA_PKCS_V15 0
|
||||||
|
#define RSA_PKCS_V21 1
|
||||||
|
|
||||||
|
#define RSA_SIGN 1
|
||||||
|
#define RSA_CRYPT 2
|
||||||
|
|
||||||
|
#define ASN1_STR_CONSTRUCTED_SEQUENCE "\x30"
|
||||||
|
#define ASN1_STR_NULL "\x05"
|
||||||
|
#define ASN1_STR_OID "\x06"
|
||||||
|
#define ASN1_STR_OCTET_STRING "\x04"
|
||||||
|
|
||||||
|
#define OID_DIGEST_ALG_MDX "\x2A\x86\x48\x86\xF7\x0D\x02\x00"
|
||||||
|
#define OID_HASH_ALG_SHA1 "\x2b\x0e\x03\x02\x1a"
|
||||||
|
#define OID_HASH_ALG_SHA2X "\x60\x86\x48\x01\x65\x03\x04\x02\x00"
|
||||||
|
|
||||||
|
#define OID_ISO_MEMBER_BODIES "\x2a"
|
||||||
|
#define OID_ISO_IDENTIFIED_ORG "\x2b"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ISO Member bodies OID parts
|
||||||
|
*/
|
||||||
|
#define OID_COUNTRY_US "\x86\x48"
|
||||||
|
#define OID_RSA_DATA_SECURITY "\x86\xf7\x0d"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ISO Identified organization OID parts
|
||||||
|
*/
|
||||||
|
#define OID_OIW_SECSIG_SHA1 "\x0e\x03\x02\x1a"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DigestInfo ::= SEQUENCE {
|
||||||
|
* digestAlgorithm DigestAlgorithmIdentifier,
|
||||||
|
* digest Digest }
|
||||||
|
*
|
||||||
|
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||||
|
*
|
||||||
|
* Digest ::= OCTET STRING
|
||||||
|
*/
|
||||||
|
#define ASN1_HASH_MDX \
|
||||||
|
( \
|
||||||
|
ASN1_STR_CONSTRUCTED_SEQUENCE "\x20" \
|
||||||
|
ASN1_STR_CONSTRUCTED_SEQUENCE "\x0C" \
|
||||||
|
ASN1_STR_OID "\x08" \
|
||||||
|
OID_DIGEST_ALG_MDX \
|
||||||
|
ASN1_STR_NULL "\x00" \
|
||||||
|
ASN1_STR_OCTET_STRING "\x10" \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define ASN1_HASH_SHA1 \
|
||||||
|
ASN1_STR_CONSTRUCTED_SEQUENCE "\x21" \
|
||||||
|
ASN1_STR_CONSTRUCTED_SEQUENCE "\x09" \
|
||||||
|
ASN1_STR_OID "\x05" \
|
||||||
|
OID_HASH_ALG_SHA1 \
|
||||||
|
ASN1_STR_NULL "\x00" \
|
||||||
|
ASN1_STR_OCTET_STRING "\x14"
|
||||||
|
|
||||||
|
#define ASN1_HASH_SHA2X \
|
||||||
|
ASN1_STR_CONSTRUCTED_SEQUENCE "\x11" \
|
||||||
|
ASN1_STR_CONSTRUCTED_SEQUENCE "\x0d" \
|
||||||
|
ASN1_STR_OID "\x09" \
|
||||||
|
OID_HASH_ALG_SHA2X \
|
||||||
|
ASN1_STR_NULL "\x00" \
|
||||||
|
ASN1_STR_OCTET_STRING "\x00"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief RSA context structure
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int ver; /*!< always 0 */
|
||||||
|
int len; /*!< size(N) in chars */
|
||||||
|
|
||||||
|
mpi N; /*!< public modulus */
|
||||||
|
mpi E; /*!< public exponent */
|
||||||
|
|
||||||
|
mpi D; /*!< private exponent */
|
||||||
|
mpi P; /*!< 1st prime factor */
|
||||||
|
mpi Q; /*!< 2nd prime factor */
|
||||||
|
mpi DP; /*!< D % (P - 1) */
|
||||||
|
mpi DQ; /*!< D % (Q - 1) */
|
||||||
|
mpi QP; /*!< 1 / (Q % P) */
|
||||||
|
|
||||||
|
mpi RN; /*!< cached R^2 mod N */
|
||||||
|
mpi RP; /*!< cached R^2 mod P */
|
||||||
|
mpi RQ; /*!< cached R^2 mod Q */
|
||||||
|
|
||||||
|
int padding; /*!< 1.5 or OAEP/PSS */
|
||||||
|
int hash_id; /*!< hash identifier */
|
||||||
|
}
|
||||||
|
rsa_context;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initialize an RSA context
|
||||||
|
*
|
||||||
|
* \param ctx RSA context to be initialized
|
||||||
|
* \param padding RSA_PKCS_V15 or RSA_PKCS_V21
|
||||||
|
* \param hash_id RSA_PKCS_V21 hash identifier
|
||||||
|
*
|
||||||
|
* \note The hash_id parameter is actually ignored
|
||||||
|
* when using RSA_PKCS_V15 padding.
|
||||||
|
*
|
||||||
|
* \note Currently, RSA_PKCS_V21 padding
|
||||||
|
* is not supported.
|
||||||
|
*/
|
||||||
|
void rsa_init( rsa_context *ctx,
|
||||||
|
int padding,
|
||||||
|
int hash_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Generate an RSA keypair
|
||||||
|
*
|
||||||
|
* \param ctx RSA context that will hold the key
|
||||||
|
* \param f_rng RNG function
|
||||||
|
* \param p_rng RNG parameter
|
||||||
|
* \param nbits size of the public key in bits
|
||||||
|
* \param exponent public exponent (e.g., 65537)
|
||||||
|
*
|
||||||
|
* \note rsa_init() must be called beforehand to setup
|
||||||
|
* the RSA context.
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||||
|
*/
|
||||||
|
int rsa_gen_key( rsa_context *ctx,
|
||||||
|
int (*f_rng)(void *),
|
||||||
|
void *p_rng,
|
||||||
|
int nbits, int exponent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Check a public RSA key
|
||||||
|
*
|
||||||
|
* \param ctx RSA context to be checked
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||||
|
*/
|
||||||
|
int rsa_check_pubkey( const rsa_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Check a private RSA key
|
||||||
|
*
|
||||||
|
* \param ctx RSA context to be checked
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||||
|
*/
|
||||||
|
int rsa_check_privkey( const rsa_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Do an RSA public key operation
|
||||||
|
*
|
||||||
|
* \param ctx RSA context
|
||||||
|
* \param input input buffer
|
||||||
|
* \param output output buffer
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||||
|
*
|
||||||
|
* \note This function does NOT take care of message
|
||||||
|
* padding. Also, be sure to set input[0] = 0 or assure that
|
||||||
|
* input is smaller than N.
|
||||||
|
*
|
||||||
|
* \note The input and output buffers must be large
|
||||||
|
* enough (eg. 128 bytes if RSA-1024 is used).
|
||||||
|
*/
|
||||||
|
int rsa_public( rsa_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Do an RSA private key operation
|
||||||
|
*
|
||||||
|
* \param ctx RSA context
|
||||||
|
* \param input input buffer
|
||||||
|
* \param output output buffer
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||||
|
*
|
||||||
|
* \note The input and output buffers must be large
|
||||||
|
* enough (eg. 128 bytes if RSA-1024 is used).
|
||||||
|
*/
|
||||||
|
int rsa_private( rsa_context *ctx,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Add the message padding, then do an RSA operation
|
||||||
|
*
|
||||||
|
* \param ctx RSA context
|
||||||
|
* \param f_rng RNG function
|
||||||
|
* \param p_rng RNG parameter
|
||||||
|
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||||
|
* \param ilen contains the plaintext length
|
||||||
|
* \param input buffer holding the data to be encrypted
|
||||||
|
* \param output buffer that will hold the ciphertext
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||||
|
*
|
||||||
|
* \note The output buffer must be as large as the size
|
||||||
|
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_encrypt( rsa_context *ctx,
|
||||||
|
int (*f_rng)(void *),
|
||||||
|
void *p_rng,
|
||||||
|
int mode, int ilen,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Do an RSA operation, then remove the message padding
|
||||||
|
*
|
||||||
|
* \param ctx RSA context
|
||||||
|
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||||
|
* \param input buffer holding the encrypted data
|
||||||
|
* \param output buffer that will hold the plaintext
|
||||||
|
* \param olen will contain the plaintext length
|
||||||
|
* \param output_max_len maximum length of the output buffer
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||||
|
*
|
||||||
|
* \note The output buffer must be as large as the size
|
||||||
|
* of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
|
||||||
|
* an error is thrown.
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||||
|
int mode, int *olen,
|
||||||
|
const unsigned char *input,
|
||||||
|
unsigned char *output,
|
||||||
|
int output_max_len );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Do a private RSA to sign a message digest
|
||||||
|
*
|
||||||
|
* \param ctx RSA context
|
||||||
|
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||||
|
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||||
|
* \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||||
|
* \param hash buffer holding the message digest
|
||||||
|
* \param sig buffer that will hold the ciphertext
|
||||||
|
*
|
||||||
|
* \return 0 if the signing operation was successful,
|
||||||
|
* or an POLARSSL_ERR_RSA_XXX error code
|
||||||
|
*
|
||||||
|
* \note The "sig" buffer must be as large as the size
|
||||||
|
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_sign( rsa_context *ctx,
|
||||||
|
int mode,
|
||||||
|
int hash_id,
|
||||||
|
int hashlen,
|
||||||
|
const unsigned char *hash,
|
||||||
|
unsigned char *sig );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Do a public RSA and check the message digest
|
||||||
|
*
|
||||||
|
* \param ctx points to an RSA public key
|
||||||
|
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||||
|
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||||
|
* \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||||
|
* \param hash buffer holding the message digest
|
||||||
|
* \param sig buffer holding the ciphertext
|
||||||
|
*
|
||||||
|
* \return 0 if the verify operation was successful,
|
||||||
|
* or an POLARSSL_ERR_RSA_XXX error code
|
||||||
|
*
|
||||||
|
* \note The "sig" buffer must be as large as the size
|
||||||
|
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||||
|
*/
|
||||||
|
int rsa_pkcs1_verify( rsa_context *ctx,
|
||||||
|
int mode,
|
||||||
|
int hash_id,
|
||||||
|
int hashlen,
|
||||||
|
const unsigned char *hash,
|
||||||
|
unsigned char *sig );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Free the components of an RSA key
|
||||||
|
*
|
||||||
|
* \param ctx RSA Context to free
|
||||||
|
*/
|
||||||
|
void rsa_free( rsa_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checkup routine
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or 1 if the test failed
|
||||||
|
*/
|
||||||
|
int rsa_self_test( int verbose );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* rsa.h */
|
702
externals/ctrtool/polarssl/sha2.c
vendored
Normal file
702
externals/ctrtool/polarssl/sha2.c
vendored
Normal file
@ -0,0 +1,702 @@
|
|||||||
|
/*
|
||||||
|
* FIPS-180-2 compliant SHA-256 implementation
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2010, Brainspark B.V.
|
||||||
|
*
|
||||||
|
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||||
|
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
|
||||||
|
*
|
||||||
|
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SHA2_C)
|
||||||
|
|
||||||
|
#include "sha2.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 32-bit integer manipulation macros (big endian)
|
||||||
|
*/
|
||||||
|
#ifndef GET_ULONG_BE
|
||||||
|
#define GET_ULONG_BE(n,b,i) \
|
||||||
|
{ \
|
||||||
|
(n) = ( (unsigned long) (b)[(i) ] << 24 ) \
|
||||||
|
| ( (unsigned long) (b)[(i) + 1] << 16 ) \
|
||||||
|
| ( (unsigned long) (b)[(i) + 2] << 8 ) \
|
||||||
|
| ( (unsigned long) (b)[(i) + 3] ); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PUT_ULONG_BE
|
||||||
|
#define PUT_ULONG_BE(n,b,i) \
|
||||||
|
{ \
|
||||||
|
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||||
|
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||||
|
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||||
|
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 context setup
|
||||||
|
*/
|
||||||
|
void sha2_starts( sha2_context *ctx, int is224 )
|
||||||
|
{
|
||||||
|
ctx->total[0] = 0;
|
||||||
|
ctx->total[1] = 0;
|
||||||
|
|
||||||
|
if( is224 == 0 )
|
||||||
|
{
|
||||||
|
/* SHA-256 */
|
||||||
|
ctx->state[0] = 0x6A09E667;
|
||||||
|
ctx->state[1] = 0xBB67AE85;
|
||||||
|
ctx->state[2] = 0x3C6EF372;
|
||||||
|
ctx->state[3] = 0xA54FF53A;
|
||||||
|
ctx->state[4] = 0x510E527F;
|
||||||
|
ctx->state[5] = 0x9B05688C;
|
||||||
|
ctx->state[6] = 0x1F83D9AB;
|
||||||
|
ctx->state[7] = 0x5BE0CD19;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* SHA-224 */
|
||||||
|
ctx->state[0] = 0xC1059ED8;
|
||||||
|
ctx->state[1] = 0x367CD507;
|
||||||
|
ctx->state[2] = 0x3070DD17;
|
||||||
|
ctx->state[3] = 0xF70E5939;
|
||||||
|
ctx->state[4] = 0xFFC00B31;
|
||||||
|
ctx->state[5] = 0x68581511;
|
||||||
|
ctx->state[6] = 0x64F98FA7;
|
||||||
|
ctx->state[7] = 0xBEFA4FA4;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->is224 = is224;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sha2_process( sha2_context *ctx, const unsigned char data[64] )
|
||||||
|
{
|
||||||
|
unsigned long temp1, temp2, W[64];
|
||||||
|
unsigned long A, B, C, D, E, F, G, H;
|
||||||
|
|
||||||
|
GET_ULONG_BE( W[ 0], data, 0 );
|
||||||
|
GET_ULONG_BE( W[ 1], data, 4 );
|
||||||
|
GET_ULONG_BE( W[ 2], data, 8 );
|
||||||
|
GET_ULONG_BE( W[ 3], data, 12 );
|
||||||
|
GET_ULONG_BE( W[ 4], data, 16 );
|
||||||
|
GET_ULONG_BE( W[ 5], data, 20 );
|
||||||
|
GET_ULONG_BE( W[ 6], data, 24 );
|
||||||
|
GET_ULONG_BE( W[ 7], data, 28 );
|
||||||
|
GET_ULONG_BE( W[ 8], data, 32 );
|
||||||
|
GET_ULONG_BE( W[ 9], data, 36 );
|
||||||
|
GET_ULONG_BE( W[10], data, 40 );
|
||||||
|
GET_ULONG_BE( W[11], data, 44 );
|
||||||
|
GET_ULONG_BE( W[12], data, 48 );
|
||||||
|
GET_ULONG_BE( W[13], data, 52 );
|
||||||
|
GET_ULONG_BE( W[14], data, 56 );
|
||||||
|
GET_ULONG_BE( W[15], data, 60 );
|
||||||
|
|
||||||
|
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
|
||||||
|
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
|
||||||
|
|
||||||
|
#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
|
||||||
|
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
|
||||||
|
|
||||||
|
#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
|
||||||
|
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
|
||||||
|
|
||||||
|
#define F0(x,y,z) ((x & y) | (z & (x | y)))
|
||||||
|
#define F1(x,y,z) (z ^ (x & (y ^ z)))
|
||||||
|
|
||||||
|
#define R(t) \
|
||||||
|
( \
|
||||||
|
W[t] = S1(W[t - 2]) + W[t - 7] + \
|
||||||
|
S0(W[t - 15]) + W[t - 16] \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define P(a,b,c,d,e,f,g,h,x,K) \
|
||||||
|
{ \
|
||||||
|
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
|
||||||
|
temp2 = S2(a) + F0(a,b,c); \
|
||||||
|
d += temp1; h = temp1 + temp2; \
|
||||||
|
}
|
||||||
|
|
||||||
|
A = ctx->state[0];
|
||||||
|
B = ctx->state[1];
|
||||||
|
C = ctx->state[2];
|
||||||
|
D = ctx->state[3];
|
||||||
|
E = ctx->state[4];
|
||||||
|
F = ctx->state[5];
|
||||||
|
G = ctx->state[6];
|
||||||
|
H = ctx->state[7];
|
||||||
|
|
||||||
|
P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
|
||||||
|
P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
|
||||||
|
P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
|
||||||
|
P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
|
||||||
|
P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
|
||||||
|
P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
|
||||||
|
P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
|
||||||
|
P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
|
||||||
|
P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
|
||||||
|
P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
|
||||||
|
P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
|
||||||
|
P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
|
||||||
|
P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
|
||||||
|
P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
|
||||||
|
P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
|
||||||
|
P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
|
||||||
|
P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
|
||||||
|
P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
|
||||||
|
P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
|
||||||
|
P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
|
||||||
|
P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
|
||||||
|
P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
|
||||||
|
P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
|
||||||
|
P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
|
||||||
|
|
||||||
|
ctx->state[0] += A;
|
||||||
|
ctx->state[1] += B;
|
||||||
|
ctx->state[2] += C;
|
||||||
|
ctx->state[3] += D;
|
||||||
|
ctx->state[4] += E;
|
||||||
|
ctx->state[5] += F;
|
||||||
|
ctx->state[6] += G;
|
||||||
|
ctx->state[7] += H;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 process buffer
|
||||||
|
*/
|
||||||
|
void sha2_update( sha2_context *ctx, const unsigned char *input, int ilen )
|
||||||
|
{
|
||||||
|
int fill;
|
||||||
|
unsigned long left;
|
||||||
|
|
||||||
|
if( ilen <= 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
left = ctx->total[0] & 0x3F;
|
||||||
|
fill = 64 - left;
|
||||||
|
|
||||||
|
ctx->total[0] += ilen;
|
||||||
|
ctx->total[0] &= 0xFFFFFFFF;
|
||||||
|
|
||||||
|
if( ctx->total[0] < (unsigned long) ilen )
|
||||||
|
ctx->total[1]++;
|
||||||
|
|
||||||
|
if( left && ilen >= fill )
|
||||||
|
{
|
||||||
|
memcpy( (void *) (ctx->buffer + left),
|
||||||
|
(void *) input, fill );
|
||||||
|
sha2_process( ctx, ctx->buffer );
|
||||||
|
input += fill;
|
||||||
|
ilen -= fill;
|
||||||
|
left = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( ilen >= 64 )
|
||||||
|
{
|
||||||
|
sha2_process( ctx, input );
|
||||||
|
input += 64;
|
||||||
|
ilen -= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ilen > 0 )
|
||||||
|
{
|
||||||
|
memcpy( (void *) (ctx->buffer + left),
|
||||||
|
(void *) input, ilen );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const unsigned char sha2_padding[64] =
|
||||||
|
{
|
||||||
|
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 final digest
|
||||||
|
*/
|
||||||
|
void sha2_finish( sha2_context *ctx, unsigned char output[32] )
|
||||||
|
{
|
||||||
|
unsigned long last, padn;
|
||||||
|
unsigned long high, low;
|
||||||
|
unsigned char msglen[8];
|
||||||
|
|
||||||
|
high = ( ctx->total[0] >> 29 )
|
||||||
|
| ( ctx->total[1] << 3 );
|
||||||
|
low = ( ctx->total[0] << 3 );
|
||||||
|
|
||||||
|
PUT_ULONG_BE( high, msglen, 0 );
|
||||||
|
PUT_ULONG_BE( low, msglen, 4 );
|
||||||
|
|
||||||
|
last = ctx->total[0] & 0x3F;
|
||||||
|
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||||
|
|
||||||
|
sha2_update( ctx, (unsigned char *) sha2_padding, padn );
|
||||||
|
sha2_update( ctx, msglen, 8 );
|
||||||
|
|
||||||
|
PUT_ULONG_BE( ctx->state[0], output, 0 );
|
||||||
|
PUT_ULONG_BE( ctx->state[1], output, 4 );
|
||||||
|
PUT_ULONG_BE( ctx->state[2], output, 8 );
|
||||||
|
PUT_ULONG_BE( ctx->state[3], output, 12 );
|
||||||
|
PUT_ULONG_BE( ctx->state[4], output, 16 );
|
||||||
|
PUT_ULONG_BE( ctx->state[5], output, 20 );
|
||||||
|
PUT_ULONG_BE( ctx->state[6], output, 24 );
|
||||||
|
|
||||||
|
if( ctx->is224 == 0 )
|
||||||
|
PUT_ULONG_BE( ctx->state[7], output, 28 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output = SHA-256( input buffer )
|
||||||
|
*/
|
||||||
|
void sha2( const unsigned char *input, int ilen,
|
||||||
|
unsigned char output[32], int is224 )
|
||||||
|
{
|
||||||
|
sha2_context ctx;
|
||||||
|
|
||||||
|
sha2_starts( &ctx, is224 );
|
||||||
|
sha2_update( &ctx, input, ilen );
|
||||||
|
sha2_finish( &ctx, output );
|
||||||
|
|
||||||
|
memset( &ctx, 0, sizeof( sha2_context ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output = SHA-256( file contents )
|
||||||
|
*/
|
||||||
|
int sha2_file( const char *path, unsigned char output[32], int is224 )
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
size_t n;
|
||||||
|
sha2_context ctx;
|
||||||
|
unsigned char buf[1024];
|
||||||
|
|
||||||
|
if( ( f = fopen( path, "rb" ) ) == NULL )
|
||||||
|
return( 1 );
|
||||||
|
|
||||||
|
sha2_starts( &ctx, is224 );
|
||||||
|
|
||||||
|
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
|
||||||
|
sha2_update( &ctx, buf, (int) n );
|
||||||
|
|
||||||
|
sha2_finish( &ctx, output );
|
||||||
|
|
||||||
|
memset( &ctx, 0, sizeof( sha2_context ) );
|
||||||
|
|
||||||
|
if( ferror( f ) != 0 )
|
||||||
|
{
|
||||||
|
fclose( f );
|
||||||
|
return( 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( f );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 HMAC context setup
|
||||||
|
*/
|
||||||
|
void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen,
|
||||||
|
int is224 )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char sum[32];
|
||||||
|
|
||||||
|
if( keylen > 64 )
|
||||||
|
{
|
||||||
|
sha2( key, keylen, sum, is224 );
|
||||||
|
keylen = ( is224 ) ? 28 : 32;
|
||||||
|
key = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset( ctx->ipad, 0x36, 64 );
|
||||||
|
memset( ctx->opad, 0x5C, 64 );
|
||||||
|
|
||||||
|
for( i = 0; i < keylen; i++ )
|
||||||
|
{
|
||||||
|
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
|
||||||
|
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
sha2_starts( ctx, is224 );
|
||||||
|
sha2_update( ctx, ctx->ipad, 64 );
|
||||||
|
|
||||||
|
memset( sum, 0, sizeof( sum ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 HMAC process buffer
|
||||||
|
*/
|
||||||
|
void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen )
|
||||||
|
{
|
||||||
|
sha2_update( ctx, input, ilen );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 HMAC final digest
|
||||||
|
*/
|
||||||
|
void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] )
|
||||||
|
{
|
||||||
|
int is224, hlen;
|
||||||
|
unsigned char tmpbuf[32];
|
||||||
|
|
||||||
|
is224 = ctx->is224;
|
||||||
|
hlen = ( is224 == 0 ) ? 32 : 28;
|
||||||
|
|
||||||
|
sha2_finish( ctx, tmpbuf );
|
||||||
|
sha2_starts( ctx, is224 );
|
||||||
|
sha2_update( ctx, ctx->opad, 64 );
|
||||||
|
sha2_update( ctx, tmpbuf, hlen );
|
||||||
|
sha2_finish( ctx, output );
|
||||||
|
|
||||||
|
memset( tmpbuf, 0, sizeof( tmpbuf ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 HMAC context reset
|
||||||
|
*/
|
||||||
|
void sha2_hmac_reset( sha2_context *ctx )
|
||||||
|
{
|
||||||
|
sha2_starts( ctx, ctx->is224 );
|
||||||
|
sha2_update( ctx, ctx->ipad, 64 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* output = HMAC-SHA-256( hmac key, input buffer )
|
||||||
|
*/
|
||||||
|
void sha2_hmac( const unsigned char *key, int keylen,
|
||||||
|
const unsigned char *input, int ilen,
|
||||||
|
unsigned char output[32], int is224 )
|
||||||
|
{
|
||||||
|
sha2_context ctx;
|
||||||
|
|
||||||
|
sha2_hmac_starts( &ctx, key, keylen, is224 );
|
||||||
|
sha2_hmac_update( &ctx, input, ilen );
|
||||||
|
sha2_hmac_finish( &ctx, output );
|
||||||
|
|
||||||
|
memset( &ctx, 0, sizeof( sha2_context ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(POLARSSL_SELF_TEST)
|
||||||
|
/*
|
||||||
|
* FIPS-180-2 test vectors
|
||||||
|
*/
|
||||||
|
static unsigned char sha2_test_buf[3][57] =
|
||||||
|
{
|
||||||
|
{ "abc" },
|
||||||
|
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
|
||||||
|
{ "" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int sha2_test_buflen[3] =
|
||||||
|
{
|
||||||
|
3, 56, 1000
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char sha2_test_sum[6][32] =
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* SHA-224 test vectors
|
||||||
|
*/
|
||||||
|
{ 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
|
||||||
|
0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
|
||||||
|
0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
|
||||||
|
0xE3, 0x6C, 0x9D, 0xA7 },
|
||||||
|
{ 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
|
||||||
|
0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
|
||||||
|
0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
|
||||||
|
0x52, 0x52, 0x25, 0x25 },
|
||||||
|
{ 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
|
||||||
|
0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
|
||||||
|
0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
|
||||||
|
0x4E, 0xE7, 0xAD, 0x67 },
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SHA-256 test vectors
|
||||||
|
*/
|
||||||
|
{ 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
|
||||||
|
0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
|
||||||
|
0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
|
||||||
|
0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
|
||||||
|
{ 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
|
||||||
|
0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
|
||||||
|
0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
|
||||||
|
0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
|
||||||
|
{ 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
|
||||||
|
0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
|
||||||
|
0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
|
||||||
|
0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RFC 4231 test vectors
|
||||||
|
*/
|
||||||
|
static unsigned char sha2_hmac_test_key[7][26] =
|
||||||
|
{
|
||||||
|
{ "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
|
||||||
|
"\x0B\x0B\x0B\x0B" },
|
||||||
|
{ "Jefe" },
|
||||||
|
{ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
|
||||||
|
"\xAA\xAA\xAA\xAA" },
|
||||||
|
{ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
|
||||||
|
"\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
|
||||||
|
{ "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
|
||||||
|
"\x0C\x0C\x0C\x0C" },
|
||||||
|
{ "" }, /* 0xAA 131 times */
|
||||||
|
{ "" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int sha2_hmac_test_keylen[7] =
|
||||||
|
{
|
||||||
|
20, 4, 20, 25, 20, 131, 131
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char sha2_hmac_test_buf[7][153] =
|
||||||
|
{
|
||||||
|
{ "Hi There" },
|
||||||
|
{ "what do ya want for nothing?" },
|
||||||
|
{ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||||
|
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||||
|
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||||
|
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
|
||||||
|
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
|
||||||
|
{ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||||
|
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||||
|
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||||
|
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
|
||||||
|
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
|
||||||
|
{ "Test With Truncation" },
|
||||||
|
{ "Test Using Larger Than Block-Size Key - Hash Key First" },
|
||||||
|
{ "This is a test using a larger than block-size key "
|
||||||
|
"and a larger than block-size data. The key needs to "
|
||||||
|
"be hashed before being used by the HMAC algorithm." }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int sha2_hmac_test_buflen[7] =
|
||||||
|
{
|
||||||
|
8, 28, 50, 50, 20, 54, 152
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char sha2_hmac_test_sum[14][32] =
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* HMAC-SHA-224 test vectors
|
||||||
|
*/
|
||||||
|
{ 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19,
|
||||||
|
0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F,
|
||||||
|
0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F,
|
||||||
|
0x53, 0x68, 0x4B, 0x22 },
|
||||||
|
{ 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF,
|
||||||
|
0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F,
|
||||||
|
0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00,
|
||||||
|
0x8F, 0xD0, 0x5E, 0x44 },
|
||||||
|
{ 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6,
|
||||||
|
0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64,
|
||||||
|
0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1,
|
||||||
|
0xEC, 0x83, 0x33, 0xEA },
|
||||||
|
{ 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC,
|
||||||
|
0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C,
|
||||||
|
0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D,
|
||||||
|
0xE7, 0xAF, 0xEC, 0x5A },
|
||||||
|
{ 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37,
|
||||||
|
0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 },
|
||||||
|
{ 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD,
|
||||||
|
0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2,
|
||||||
|
0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27,
|
||||||
|
0x3F, 0xA6, 0x87, 0x0E },
|
||||||
|
{ 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02,
|
||||||
|
0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD,
|
||||||
|
0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9,
|
||||||
|
0xF6, 0xF5, 0x65, 0xD1 },
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HMAC-SHA-256 test vectors
|
||||||
|
*/
|
||||||
|
{ 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53,
|
||||||
|
0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B,
|
||||||
|
0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7,
|
||||||
|
0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 },
|
||||||
|
{ 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E,
|
||||||
|
0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7,
|
||||||
|
0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83,
|
||||||
|
0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 },
|
||||||
|
{ 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46,
|
||||||
|
0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7,
|
||||||
|
0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22,
|
||||||
|
0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE },
|
||||||
|
{ 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E,
|
||||||
|
0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A,
|
||||||
|
0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07,
|
||||||
|
0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B },
|
||||||
|
{ 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0,
|
||||||
|
0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B },
|
||||||
|
{ 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F,
|
||||||
|
0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F,
|
||||||
|
0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14,
|
||||||
|
0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 },
|
||||||
|
{ 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB,
|
||||||
|
0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44,
|
||||||
|
0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93,
|
||||||
|
0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checkup routine
|
||||||
|
*/
|
||||||
|
int sha2_self_test( int verbose )
|
||||||
|
{
|
||||||
|
int i, j, k, buflen;
|
||||||
|
unsigned char buf[1024];
|
||||||
|
unsigned char sha2sum[32];
|
||||||
|
sha2_context ctx;
|
||||||
|
|
||||||
|
for( i = 0; i < 6; i++ )
|
||||||
|
{
|
||||||
|
j = i % 3;
|
||||||
|
k = i < 3;
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
|
||||||
|
|
||||||
|
sha2_starts( &ctx, k );
|
||||||
|
|
||||||
|
if( j == 2 )
|
||||||
|
{
|
||||||
|
memset( buf, 'a', buflen = 1000 );
|
||||||
|
|
||||||
|
for( j = 0; j < 1000; j++ )
|
||||||
|
sha2_update( &ctx, buf, buflen );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sha2_update( &ctx, sha2_test_buf[j],
|
||||||
|
sha2_test_buflen[j] );
|
||||||
|
|
||||||
|
sha2_finish( &ctx, sha2sum );
|
||||||
|
|
||||||
|
if( memcmp( sha2sum, sha2_test_sum[i], 32 - k * 4 ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "\n" );
|
||||||
|
|
||||||
|
for( i = 0; i < 14; i++ )
|
||||||
|
{
|
||||||
|
j = i % 7;
|
||||||
|
k = i < 7;
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( " HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 );
|
||||||
|
|
||||||
|
if( j == 5 || j == 6 )
|
||||||
|
{
|
||||||
|
memset( buf, '\xAA', buflen = 131 );
|
||||||
|
sha2_hmac_starts( &ctx, buf, buflen, k );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sha2_hmac_starts( &ctx, sha2_hmac_test_key[j],
|
||||||
|
sha2_hmac_test_keylen[j], k );
|
||||||
|
|
||||||
|
sha2_hmac_update( &ctx, sha2_hmac_test_buf[j],
|
||||||
|
sha2_hmac_test_buflen[j] );
|
||||||
|
|
||||||
|
sha2_hmac_finish( &ctx, sha2sum );
|
||||||
|
|
||||||
|
buflen = ( j == 4 ) ? 16 : 32 - k * 4;
|
||||||
|
|
||||||
|
if( memcmp( sha2sum, sha2_hmac_test_sum[i], buflen ) != 0 )
|
||||||
|
{
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "failed\n" );
|
||||||
|
|
||||||
|
return( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "passed\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( verbose != 0 )
|
||||||
|
printf( "\n" );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
155
externals/ctrtool/polarssl/sha2.h
vendored
Normal file
155
externals/ctrtool/polarssl/sha2.h
vendored
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/**
|
||||||
|
* \file sha2.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2010, Brainspark B.V.
|
||||||
|
*
|
||||||
|
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||||
|
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
#ifndef POLARSSL_SHA2_H
|
||||||
|
#define POLARSSL_SHA2_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 context structure
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned long total[2]; /*!< number of bytes processed */
|
||||||
|
unsigned long state[8]; /*!< intermediate digest state */
|
||||||
|
unsigned char buffer[64]; /*!< data block being processed */
|
||||||
|
|
||||||
|
unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||||
|
unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||||
|
int is224; /*!< 0 => SHA-256, else SHA-224 */
|
||||||
|
}
|
||||||
|
sha2_context;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 context setup
|
||||||
|
*
|
||||||
|
* \param ctx context to be initialized
|
||||||
|
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||||
|
*/
|
||||||
|
void sha2_starts( sha2_context *ctx, int is224 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 process buffer
|
||||||
|
*
|
||||||
|
* \param ctx SHA-256 context
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
*/
|
||||||
|
void sha2_update( sha2_context *ctx, const unsigned char *input, int ilen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 final digest
|
||||||
|
*
|
||||||
|
* \param ctx SHA-256 context
|
||||||
|
* \param output SHA-224/256 checksum result
|
||||||
|
*/
|
||||||
|
void sha2_finish( sha2_context *ctx, unsigned char output[32] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Output = SHA-256( input buffer )
|
||||||
|
*
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
* \param output SHA-224/256 checksum result
|
||||||
|
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||||
|
*/
|
||||||
|
void sha2( const unsigned char *input, int ilen,
|
||||||
|
unsigned char output[32], int is224 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Output = SHA-256( file contents )
|
||||||
|
*
|
||||||
|
* \param path input file name
|
||||||
|
* \param output SHA-224/256 checksum result
|
||||||
|
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||||
|
*
|
||||||
|
* \return 0 if successful, 1 if fopen failed,
|
||||||
|
* or 2 if fread failed
|
||||||
|
*/
|
||||||
|
int sha2_file( const char *path, unsigned char output[32], int is224 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 HMAC context setup
|
||||||
|
*
|
||||||
|
* \param ctx HMAC context to be initialized
|
||||||
|
* \param key HMAC secret key
|
||||||
|
* \param keylen length of the HMAC key
|
||||||
|
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||||
|
*/
|
||||||
|
void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen,
|
||||||
|
int is224 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 HMAC process buffer
|
||||||
|
*
|
||||||
|
* \param ctx HMAC context
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
*/
|
||||||
|
void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 HMAC final digest
|
||||||
|
*
|
||||||
|
* \param ctx HMAC context
|
||||||
|
* \param output SHA-224/256 HMAC checksum result
|
||||||
|
*/
|
||||||
|
void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief SHA-256 HMAC context reset
|
||||||
|
*
|
||||||
|
* \param ctx HMAC context to be reset
|
||||||
|
*/
|
||||||
|
void sha2_hmac_reset( sha2_context *ctx );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Output = HMAC-SHA-256( hmac key, input buffer )
|
||||||
|
*
|
||||||
|
* \param key HMAC secret key
|
||||||
|
* \param keylen length of the HMAC key
|
||||||
|
* \param input buffer holding the data
|
||||||
|
* \param ilen length of the input data
|
||||||
|
* \param output HMAC-SHA-224/256 result
|
||||||
|
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||||
|
*/
|
||||||
|
void sha2_hmac( const unsigned char *key, int keylen,
|
||||||
|
const unsigned char *input, int ilen,
|
||||||
|
unsigned char output[32], int is224 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Checkup routine
|
||||||
|
*
|
||||||
|
* \return 0 if successful, or 1 if the test failed
|
||||||
|
*/
|
||||||
|
int sha2_self_test( int verbose );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* sha2.h */
|
36
externals/ctrtool/types.h
vendored
Normal file
36
externals/ctrtool/types.h
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef __TYPES_H__
|
||||||
|
#define __TYPES_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef unsigned short u16;
|
||||||
|
typedef unsigned int u32;
|
||||||
|
typedef unsigned long long u64;
|
||||||
|
|
||||||
|
typedef signed char s8;
|
||||||
|
typedef signed short s16;
|
||||||
|
typedef signed int s32;
|
||||||
|
typedef signed long long s64;
|
||||||
|
|
||||||
|
enum flags
|
||||||
|
{
|
||||||
|
ExtractFlag = (1<<0),
|
||||||
|
InfoFlag = (1<<1),
|
||||||
|
PlainFlag = (1<<2),
|
||||||
|
VerboseFlag = (1<<3),
|
||||||
|
VerifyFlag = (1<<4),
|
||||||
|
RawFlag = (1<<5),
|
||||||
|
ShowKeysFlag = (1<<6)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum validstate
|
||||||
|
{
|
||||||
|
Unchecked = 0,
|
||||||
|
Good = 1,
|
||||||
|
Fail = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -163,6 +163,8 @@ int main(int argc, char** argv) {
|
|||||||
break; // Expected case
|
break; // Expected case
|
||||||
}
|
}
|
||||||
|
|
||||||
|
system.SetExitCallback([&]{ emu_window->CloseWindow(); });
|
||||||
|
|
||||||
while (emu_window->IsOpen()) {
|
while (emu_window->IsOpen()) {
|
||||||
system.RunLoop();
|
system.RunLoop();
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,10 @@ public:
|
|||||||
/// Whether the window is still open, and a close request hasn't yet been sent
|
/// Whether the window is still open, and a close request hasn't yet been sent
|
||||||
bool IsOpen() const;
|
bool IsOpen() const;
|
||||||
|
|
||||||
|
void CloseWindow() {
|
||||||
|
is_open = false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Load keymap from configuration
|
/// Load keymap from configuration
|
||||||
void ReloadSetKeymaps() override;
|
void ReloadSetKeymaps() override;
|
||||||
|
|
||||||
|
@ -342,6 +342,8 @@ void GMainWindow::BootGame(const std::string& filename) {
|
|||||||
if (!LoadROM(filename))
|
if (!LoadROM(filename))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Core::System::GetInstance().SetExitCallback([&]{ ShutdownGame(); });
|
||||||
|
|
||||||
// Create and start the emulation thread
|
// Create and start the emulation thread
|
||||||
emu_thread = std::make_unique<EmuThread>(render_window);
|
emu_thread = std::make_unique<EmuThread>(render_window);
|
||||||
emit EmulationStarting(emu_thread.get());
|
emit EmulationStarting(emu_thread.get());
|
||||||
|
@ -77,3 +77,4 @@ add_library(common STATIC ${SRCS} ${HEADERS})
|
|||||||
if (ARCHITECTURE_x86_64)
|
if (ARCHITECTURE_x86_64)
|
||||||
target_link_libraries(common xbyak)
|
target_link_libraries(common xbyak)
|
||||||
endif()
|
endif()
|
||||||
|
target_link_libraries(common ctrtool)
|
@ -247,10 +247,21 @@ public:
|
|||||||
m_good = true;
|
m_good = true;
|
||||||
std::clearerr(m_file);
|
std::clearerr(m_file);
|
||||||
}
|
}
|
||||||
|
void SetEncrypted(bool encrypted, u8 counter[16]) {
|
||||||
|
m_encrypted = encrypted;
|
||||||
|
if(encrypted) {
|
||||||
|
memcpy(m_counter, counter, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool Encrypted() const { return m_encrypted; }
|
||||||
|
void GetCounter(u8* counter) {
|
||||||
|
std::memcpy(counter, m_counter, 16);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::FILE* m_file = nullptr;
|
std::FILE* m_file = nullptr;
|
||||||
bool m_good = true;
|
bool m_good = true;
|
||||||
|
bool m_encrypted = false;
|
||||||
|
u8 m_counter[16]{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -363,3 +363,4 @@ create_directory_groups(${SRCS} ${HEADERS})
|
|||||||
add_library(core STATIC ${SRCS} ${HEADERS})
|
add_library(core STATIC ${SRCS} ${HEADERS})
|
||||||
|
|
||||||
target_link_libraries(core dynarmic)
|
target_link_libraries(core dynarmic)
|
||||||
|
target_link_libraries(core ctrtool)
|
@ -113,6 +113,12 @@ void System::PrepareReschedule() {
|
|||||||
reschedule_pending = true;
|
reschedule_pending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void System::ExitCallback() {
|
||||||
|
if (exit_callback) {
|
||||||
|
exit_callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void System::Reschedule() {
|
void System::Reschedule() {
|
||||||
if (!reschedule_pending) {
|
if (!reschedule_pending) {
|
||||||
return;
|
return;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -83,6 +84,12 @@ public:
|
|||||||
/// Prepare the core emulation for a reschedule
|
/// Prepare the core emulation for a reschedule
|
||||||
void PrepareReschedule();
|
void PrepareReschedule();
|
||||||
|
|
||||||
|
void SetExitCallback(std::function<void()> callback) {
|
||||||
|
exit_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExitCallback();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a reference to the emulated CPU.
|
* Gets a reference to the emulated CPU.
|
||||||
* @returns A reference to the emulated CPU.
|
* @returns A reference to the emulated CPU.
|
||||||
@ -112,6 +119,8 @@ private:
|
|||||||
/// When true, signals that a reschedule should happen
|
/// When true, signals that a reschedule should happen
|
||||||
bool reschedule_pending{};
|
bool reschedule_pending{};
|
||||||
|
|
||||||
|
std::function<void()> exit_callback;
|
||||||
|
|
||||||
static System s_instance;
|
static System s_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/file_sys/ivfc_archive.h"
|
#include "core/file_sys/ivfc_archive.h"
|
||||||
|
#include "ctr.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// FileSys namespace
|
// FileSys namespace
|
||||||
@ -86,13 +87,37 @@ u64 IVFCArchive::GetFreeBytes() const {
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ResultVal<size_t> IVFCFile::Read(const u64 offset, const size_t length, u8* buffer) const {
|
ResultVal<size_t> IVFCFile::Read(const u64 offset, const size_t length, u8* buffer) const {
|
||||||
LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length);
|
LOG_TRACE(Service_FS, "called offset=0x%X, length=0x%X", offset, length);
|
||||||
romfs_file->Seek(data_offset + offset, SEEK_SET);
|
|
||||||
size_t read_length = (size_t)std::min((u64)length, data_size - offset);
|
|
||||||
|
|
||||||
return MakeResult<size_t>(romfs_file->ReadBytes(buffer, read_length));
|
if (romfs_file == nullptr) {
|
||||||
|
LOG_ERROR(Service_FS, "called with no RomFS, offset=0x%X, length=0x%X", offset, length);
|
||||||
|
return ResultVal<size_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 pad = offset & 0xF;
|
||||||
|
u64 read_offset = offset & ~0xF;
|
||||||
|
size_t read_length = (size_t)std::min((u64)(length+pad), data_size - read_offset);
|
||||||
|
romfs_file->Seek(data_offset + read_offset, SEEK_SET);
|
||||||
|
|
||||||
|
std::vector<u8> tmp_vector(read_length);
|
||||||
|
|
||||||
|
size_t readed = romfs_file->ReadBytes(tmp_vector.data(), read_length);
|
||||||
|
|
||||||
|
if (romfs_file->Encrypted()) {
|
||||||
|
u8 key[16]{};
|
||||||
|
u8 counter[16]{};
|
||||||
|
ctr_aes_context aes{};
|
||||||
|
romfs_file->GetCounter(counter);
|
||||||
|
ctr_init_counter(&aes, key, counter);
|
||||||
|
ctr_add_counter(&aes, (read_offset+0x1000) / 0x10);
|
||||||
|
ctr_crypt_counter(&aes, tmp_vector.data(), tmp_vector.data(), readed);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memcpy(buffer, tmp_vector.data() + pad, readed - pad);
|
||||||
|
return MakeResult<size_t>(readed - pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ResultVal<size_t> IVFCFile::Write(const u64 offset, const size_t length, const bool flush,
|
ResultVal<size_t> IVFCFile::Write(const u64 offset, const size_t length, const bool flush,
|
||||||
const u8* buffer) const {
|
const u8* buffer) const {
|
||||||
LOG_ERROR(Service_FS, "Attempted to write to IVFC file");
|
LOG_ERROR(Service_FS, "Attempted to write to IVFC file");
|
||||||
|
@ -36,7 +36,7 @@ void GetAdapterState(Service::Interface* self) {
|
|||||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||||
cmd_buff[2] = battery_is_charging ? 1 : 0;
|
cmd_buff[2] = battery_is_charging ? 1 : 0;
|
||||||
|
|
||||||
LOG_WARNING(Service_PTM, "(STUBBED) called");
|
LOG_WARNING(Service_PTM, "(STUBBED) called, charging=%u", battery_is_charging);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetShellState(Service::Interface* self) {
|
void GetShellState(Service::Interface* self) {
|
||||||
|
@ -72,6 +72,7 @@ void Init() {
|
|||||||
|
|
||||||
// Some games wait until this value becomes 0x1, before asking running_hw
|
// Some games wait until this value becomes 0x1, before asking running_hw
|
||||||
shared_page.unknown_value = 0x1;
|
shared_page.unknown_value = 0x1;
|
||||||
|
shared_page.battery_led_state = 0xF;
|
||||||
|
|
||||||
update_time_event =
|
update_time_event =
|
||||||
CoreTiming::RegisterEvent("SharedPage::UpdateTimeCallback", UpdateTimeCallback);
|
CoreTiming::RegisterEvent("SharedPage::UpdateTimeCallback", UpdateTimeCallback);
|
||||||
|
@ -44,7 +44,7 @@ struct SharedPageDef {
|
|||||||
INSERT_PADDING_BYTES(0x80 - 0x68); // 68
|
INSERT_PADDING_BYTES(0x80 - 0x68); // 68
|
||||||
float_le sliderstate_3d; // 80
|
float_le sliderstate_3d; // 80
|
||||||
u8 ledstate_3d; // 84
|
u8 ledstate_3d; // 84
|
||||||
INSERT_PADDING_BYTES(1); // 85
|
u8 battery_led_state; // 85
|
||||||
u8 unknown_value; // 86
|
u8 unknown_value; // 86
|
||||||
INSERT_PADDING_BYTES(0xA0 - 0x87); // 87
|
INSERT_PADDING_BYTES(0xA0 - 0x87); // 87
|
||||||
u64_le menu_title_id; // A0
|
u64_le menu_title_id; // A0
|
||||||
|
@ -468,7 +468,7 @@ static void Break(u8 break_reason) {
|
|||||||
|
|
||||||
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
|
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
|
||||||
static void OutputDebugString(const char* string) {
|
static void OutputDebugString(const char* string) {
|
||||||
LOG_DEBUG(Debug_Emulated, "%s", string);
|
LOG_INFO(Debug_Emulated, "%s", string);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get resource limit
|
/// Get resource limit
|
||||||
@ -770,6 +770,12 @@ static ResultCode CreateEvent(Kernel::Handle* out_handle, u32 reset_type) {
|
|||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Exit current process
|
||||||
|
static void ExitProcess() {
|
||||||
|
LOG_WARNING(Kernel_SVC, "called");
|
||||||
|
Core::System::GetInstance().ExitCallback();
|
||||||
|
}
|
||||||
|
|
||||||
/// Duplicates a kernel handle
|
/// Duplicates a kernel handle
|
||||||
static ResultCode DuplicateHandle(Kernel::Handle* out, Kernel::Handle handle) {
|
static ResultCode DuplicateHandle(Kernel::Handle* out, Kernel::Handle handle) {
|
||||||
CASCADE_RESULT(*out, Kernel::g_handle_table.Duplicate(handle));
|
CASCADE_RESULT(*out, Kernel::g_handle_table.Duplicate(handle));
|
||||||
@ -1074,7 +1080,7 @@ static const FunctionDef SVC_Table[] = {
|
|||||||
{0x00, nullptr, "Unknown"},
|
{0x00, nullptr, "Unknown"},
|
||||||
{0x01, HLE::Wrap<ControlMemory>, "ControlMemory"},
|
{0x01, HLE::Wrap<ControlMemory>, "ControlMemory"},
|
||||||
{0x02, HLE::Wrap<QueryMemory>, "QueryMemory"},
|
{0x02, HLE::Wrap<QueryMemory>, "QueryMemory"},
|
||||||
{0x03, nullptr, "ExitProcess"},
|
{0x03, ExitProcess, "ExitProcess"},
|
||||||
{0x04, nullptr, "GetProcessAffinityMask"},
|
{0x04, nullptr, "GetProcessAffinityMask"},
|
||||||
{0x05, nullptr, "SetProcessAffinityMask"},
|
{0x05, nullptr, "SetProcessAffinityMask"},
|
||||||
{0x06, nullptr, "GetProcessIdealProcessor"},
|
{0x06, nullptr, "GetProcessIdealProcessor"},
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "core/loader/ncch.h"
|
#include "core/loader/ncch.h"
|
||||||
#include "core/loader/smdh.h"
|
#include "core/loader/smdh.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
#include "ctr.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Loader namespace
|
// Loader namespace
|
||||||
@ -221,6 +222,14 @@ ResultStatus AppLoader_NCCH::LoadSectionExeFS(const char* name, std::vector<u8>&
|
|||||||
if (file.ReadBytes(&temp_buffer[0], section.size) != section.size)
|
if (file.ReadBytes(&temp_buffer[0], section.size) != section.size)
|
||||||
return ResultStatus::Error;
|
return ResultStatus::Error;
|
||||||
|
|
||||||
|
if (is_encrypted) {
|
||||||
|
memset(&key, 0, sizeof(key));
|
||||||
|
ctr_init_counter(&aes, key, exefscounter);
|
||||||
|
ctr_add_counter(&aes, (section.offset + sizeof(ExeFs_Header)) / 0x10);
|
||||||
|
ctr_crypt_counter(&aes, (u8*)&temp_buffer[0], (u8*)&temp_buffer[0],
|
||||||
|
section.size);
|
||||||
|
}
|
||||||
|
|
||||||
// Decompress .code section...
|
// Decompress .code section...
|
||||||
u32 decompressed_size = LZSS_GetDecompressedSize(&temp_buffer[0], section.size);
|
u32 decompressed_size = LZSS_GetDecompressedSize(&temp_buffer[0], section.size);
|
||||||
buffer.resize(decompressed_size);
|
buffer.resize(decompressed_size);
|
||||||
@ -231,6 +240,13 @@ ResultStatus AppLoader_NCCH::LoadSectionExeFS(const char* name, std::vector<u8>&
|
|||||||
buffer.resize(section.size);
|
buffer.resize(section.size);
|
||||||
if (file.ReadBytes(&buffer[0], section.size) != section.size)
|
if (file.ReadBytes(&buffer[0], section.size) != section.size)
|
||||||
return ResultStatus::Error;
|
return ResultStatus::Error;
|
||||||
|
if (is_encrypted) {
|
||||||
|
memset(&key, 0, sizeof(key));
|
||||||
|
ctr_init_counter(&aes, key, exefscounter);
|
||||||
|
ctr_add_counter(&aes, (section.offset + sizeof(ExeFs_Header)) / 0x10);
|
||||||
|
ctr_crypt_counter(&aes, (u8*)&buffer[0], (u8*)&buffer[0],
|
||||||
|
section.size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ResultStatus::Success;
|
return ResultStatus::Success;
|
||||||
}
|
}
|
||||||
@ -268,6 +284,32 @@ ResultStatus AppLoader_NCCH::LoadExeFS() {
|
|||||||
if (file.ReadBytes(&exheader_header, sizeof(ExHeader_Header)) != sizeof(ExHeader_Header))
|
if (file.ReadBytes(&exheader_header, sizeof(ExHeader_Header)) != sizeof(ExHeader_Header))
|
||||||
return ResultStatus::Error;
|
return ResultStatus::Error;
|
||||||
|
|
||||||
|
// Check if ExHeader encrypted
|
||||||
|
if (memcmp(&exheader_header.arm11_system_local_caps.program_id, &ncch_header.program_id, 8)) {
|
||||||
|
// Fixed Crypto Key
|
||||||
|
if (ncch_header.flags[7] & 0x1) {
|
||||||
|
is_encrypted = true;
|
||||||
|
memset(&exheadercounter, 0, sizeof(exheadercounter));
|
||||||
|
memset(&exefscounter, 0, sizeof(exefscounter));
|
||||||
|
memset(&romfscounter, 0, sizeof(romfscounter));
|
||||||
|
if (ncch_header.version == 2 || ncch_header.version == 0) {
|
||||||
|
for (u8 i = 0; i < 8; i++) {
|
||||||
|
exefscounter[i] = romfscounter[i] = exheadercounter[i] =
|
||||||
|
ncch_header.partition_id[7 - i];
|
||||||
|
}
|
||||||
|
exheadercounter[8] = 1;
|
||||||
|
exefscounter[8] = 2;
|
||||||
|
romfscounter[8] = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_encrypted) {
|
||||||
|
memset(&key, 0, sizeof(key));
|
||||||
|
ctr_init_counter(&aes, key, exheadercounter);
|
||||||
|
ctr_crypt_counter(&aes, (u8*)&exheader_header, (u8*)&exheader_header, sizeof(ExHeader_Header));
|
||||||
|
}
|
||||||
|
|
||||||
is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1;
|
is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1;
|
||||||
entry_point = exheader_header.codeset_info.text.address;
|
entry_point = exheader_header.codeset_info.text.address;
|
||||||
code_size = exheader_header.codeset_info.text.code_size;
|
code_size = exheader_header.codeset_info.text.code_size;
|
||||||
@ -307,6 +349,12 @@ ResultStatus AppLoader_NCCH::LoadExeFS() {
|
|||||||
if (file.ReadBytes(&exefs_header, sizeof(ExeFs_Header)) != sizeof(ExeFs_Header))
|
if (file.ReadBytes(&exefs_header, sizeof(ExeFs_Header)) != sizeof(ExeFs_Header))
|
||||||
return ResultStatus::Error;
|
return ResultStatus::Error;
|
||||||
|
|
||||||
|
if (is_encrypted) {
|
||||||
|
memset(&key, 0, sizeof(key));
|
||||||
|
ctr_init_counter(&aes, key, exefscounter);
|
||||||
|
ctr_crypt_counter(&aes, (u8*)&exefs_header, (u8*)&exefs_header, sizeof(ExeFs_Header));
|
||||||
|
}
|
||||||
|
|
||||||
is_exefs_loaded = true;
|
is_exefs_loaded = true;
|
||||||
return ResultStatus::Success;
|
return ResultStatus::Success;
|
||||||
}
|
}
|
||||||
@ -342,8 +390,11 @@ ResultStatus AppLoader_NCCH::Load() {
|
|||||||
if (ResultStatus::Success != result)
|
if (ResultStatus::Success != result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
// Do not register RomFS if absent
|
||||||
|
// if (ncch_header.romfs_offset != 0 && ncch_header.romfs_size != 0) {
|
||||||
Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this),
|
Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this),
|
||||||
Service::FS::ArchiveIdCode::RomFS);
|
Service::FS::ArchiveIdCode::RomFS);
|
||||||
|
// }
|
||||||
|
|
||||||
ParseRegionLockoutInfo();
|
ParseRegionLockoutInfo();
|
||||||
|
|
||||||
@ -398,6 +449,7 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_
|
|||||||
romfs_file = std::make_shared<FileUtil::IOFile>(filepath, "rb");
|
romfs_file = std::make_shared<FileUtil::IOFile>(filepath, "rb");
|
||||||
if (!romfs_file->IsOpen())
|
if (!romfs_file->IsOpen())
|
||||||
return ResultStatus::Error;
|
return ResultStatus::Error;
|
||||||
|
romfs_file->SetEncrypted(is_encrypted, romfscounter);
|
||||||
|
|
||||||
offset = romfs_offset;
|
offset = romfs_offset;
|
||||||
size = romfs_size;
|
size = romfs_size;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
|
#include "ctr.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// NCCH header (Note: "NCCH" appears to be a publicly unknown acronym)
|
/// NCCH header (Note: "NCCH" appears to be a publicly unknown acronym)
|
||||||
@ -234,6 +235,14 @@ private:
|
|||||||
|
|
||||||
bool is_exefs_loaded = false;
|
bool is_exefs_loaded = false;
|
||||||
bool is_compressed = false;
|
bool is_compressed = false;
|
||||||
|
bool is_encrypted = false;
|
||||||
|
|
||||||
|
ctr_aes_context aes{};
|
||||||
|
ctr_rsa_context rsa{};
|
||||||
|
u8 key[16]{};
|
||||||
|
u8 exheadercounter[16]{};
|
||||||
|
u8 exefscounter[16]{};
|
||||||
|
u8 romfscounter[16]{};
|
||||||
|
|
||||||
u32 entry_point = 0;
|
u32 entry_point = 0;
|
||||||
u32 code_size = 0;
|
u32 code_size = 0;
|
||||||
|
@ -147,6 +147,8 @@ static u8* GetPointerFromVMA(VAddr vaddr) {
|
|||||||
case Kernel::VMAType::BackingMemory:
|
case Kernel::VMAType::BackingMemory:
|
||||||
direct_pointer = vma.backing_memory;
|
direct_pointer = vma.backing_memory;
|
||||||
break;
|
break;
|
||||||
|
case Kernel::VMAType::Free:
|
||||||
|
return nullptr;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user