Пример #1
0
/*
    Generate an RSA keypair
 */
int rsa_gen_key(rsa_context *ctx, int nbits, int exponent)
{
    mpi     P1, Q1, H, G;
    int     ret;

    if (ctx->f_rng == NULL || nbits < 128 || exponent < 3) {
        return EST_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, ctx->f_rng, ctx->p_rng));

        MPI_CHK(mpi_gen_prime(&ctx->Q, (nbits + 1) >> 1, 0, ctx->f_rng, ctx->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 EST_ERR_RSA_KEY_GEN_FAILED | ret;
    }
    return 0;
}
Пример #2
0
/*
    Check a public RSA key
 */
int rsa_check_pubkey(rsa_context *ctx)
{
    if ((ctx->N.p[0] & 1) == 0 || (ctx->E.p[0] & 1) == 0) {
        return EST_ERR_RSA_KEY_CHECK_FAILED;
    }
    if (mpi_msb(&ctx->N) < 128 || mpi_msb(&ctx->N) > 4096) {
        return EST_ERR_RSA_KEY_CHECK_FAILED;
    }
    if (mpi_msb(&ctx->E) < 2 || mpi_msb(&ctx->E) > 64) {
        return EST_ERR_RSA_KEY_CHECK_FAILED;
    }
    return 0;
}
Пример #3
0
void
check_key_length (ssl_context *ssl)
{
  uint32_t key_bits;
  const x509_cert *certificate;
  const rsa_context *public_key;
  char buf[1024];

  certificate = ssl_get_peer_cert (ssl);
  if (NULL == certificate)
  {
    die ("Getting certificate failed");
  }

  x509parse_dn_gets(buf, 1024, &certificate->subject);
  verb_debug ("V: Certificate for subject '%s'", buf);

  public_key = &certificate->rsa;
  if (NULL == public_key)
  {
    die ("public key extraction failure");
  } else {
    verb_debug ("V: public key is ready for inspection");
  }
  key_bits = mpi_msb (&public_key->N);
  if (MIN_PUB_KEY_LEN >= key_bits)
  {
    die ("Unsafe public key size: %d bits", key_bits);
  } else {
    verb_debug ("V: key length appears safe");
  }
}
Пример #4
0
/*
 * Check a public RSA key
 */
int rsa_check_pubkey( rsa_context *ctx )
{
    if( ( ctx->N.p[0] & 1 ) == 0 || 
        ( ctx->E.p[0] & 1 ) == 0 )
        return( XYSSL_ERR_RSA_KEY_CHECK_FAILED );

    if( mpi_msb( &ctx->N ) < 128 ||
        mpi_msb( &ctx->N ) > 4096 )
        return( XYSSL_ERR_RSA_KEY_CHECK_FAILED );

    if( mpi_msb( &ctx->E ) < 2 ||
        mpi_msb( &ctx->E ) > 64 )
        return( XYSSL_ERR_RSA_KEY_CHECK_FAILED );

    return( 0 );
}
Пример #5
0
/*
 * 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 ) > POLARSSL_MPI_MAX_BITS )
        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 );
}
Пример #6
0
static int Btohex(lua_State *L)
{
    mpi *a=Bget(L,1);
    int n = mpi_msb(a);
    size_t numChars = 3 + n/4;
    char *s = (char *) malloc(numChars); /*for radix 16, we are safe with one char for every 4 bits with one extra for the terminating 0*/
    mpi_write_string(a, 16, s, &numChars);
    lua_pushstring(L,s);
    free(s);
    return 1;
}
Пример #7
0
int chiffrer_rsa(char* data, char* sortie, int taille_data )
{
    FILE *f;
    int ret;
    size_t i;
	rsa_context rsa;
    entropy_context entropy;
    ctr_drbg_context ctr_drbg;
    char *pers = "rsa_encrypt";
	
    printf( "[i] Seeding the random number generator\n" );

    entropy_init( &entropy );
    if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
                               (unsigned char *) pers, strlen( pers ) ) ) != 0 )
    {
        printf( "[-] ctr_drbg_init returned %d\n", ret );
        goto exit;
    }

    printf( "[i] Reading private key\n" );


    rsa_init( &rsa, RSA_PKCS_V15, 0 );
    
    if( ( ret = mpi_read_string( &rsa.N, RSA_N_BASE, RSA_N ) ) != 0 ||
        ( ret = mpi_read_string( &rsa.D, RSA_D_BASE, RSA_D ) ) != 0 )
    {
        printf( "[-] mpi_read_file returned %d\n", ret );
        goto exit;
    }

    rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3;


    /*
     * Calculate the RSA encryption of the hash.
     */
    printf( "[i] Generating the RSA encrypted value (%d/%d)\n", rsa.len, taille_data );
    fflush( stdout );

    if( ( ret = rsa_pkcs1_encrypt( &rsa, ctr_drbg_random, &ctr_drbg,
                                   RSA_PRIVATE, taille_data,
                                   data, sortie ) ) != 0 )
    {
        printf( "[-] rsa_pkcs1_encrypt returned %d\n\n", ret );
        goto exit;
    }
    printf( "[i] Cryptogramme copie\n");

exit:
    return( ret );
}
Пример #8
0
/*
 * 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 );   
}
Пример #9
0
/*
 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
 */
int rsa_rsassa_pss_sign( rsa_context *ctx,
                         int (*f_rng)(void *, unsigned char *, size_t),
                         void *p_rng,
                         int mode,
                         int hash_id,
                         unsigned int hashlen,
                         const unsigned char *hash,
                         unsigned char *sig )
{
    size_t olen;
    unsigned char *p = sig;
    unsigned char salt[POLARSSL_MD_MAX_SIZE];
    unsigned int slen, hlen, offset = 0;
    int ret;
    size_t msb;
    const md_info_t *md_info;
    md_context_t md_ctx;

    if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    olen = ctx->len;

    switch( hash_id )
    {
        case SIG_RSA_MD2:
        case SIG_RSA_MD4:
        case SIG_RSA_MD5:
            hashlen = 16;
            break;

        case SIG_RSA_SHA1:
            hashlen = 20;
            break;

        case SIG_RSA_SHA224:
            hashlen = 28;
            break;

        case SIG_RSA_SHA256:
            hashlen = 32;
            break;

        case SIG_RSA_SHA384:
            hashlen = 48;
            break;

        case SIG_RSA_SHA512:
            hashlen = 64;
            break;

        default:
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    md_info = md_info_from_type( ctx->hash_id );
    if( md_info == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    hlen = md_get_size( md_info );
    slen = hlen;

    if( olen < hlen + slen + 2 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    memset( sig, 0, olen );

    msb = mpi_msb( &ctx->N ) - 1;

    // Generate salt of length slen
    //
    if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
        return( POLARSSL_ERR_RSA_RNG_FAILED + ret );

    // Note: EMSA-PSS encoding is over the length of N - 1 bits
    //
    msb = mpi_msb( &ctx->N ) - 1;
    p += olen - hlen * 2 - 2;
    *p++ = 0x01;
    memcpy( p, salt, slen );
    p += slen;

    md_init_ctx( &md_ctx, md_info );

    // Generate H = Hash( M' )
    //
    md_starts( &md_ctx );
    md_update( &md_ctx, p, 8 );
    md_update( &md_ctx, hash, hashlen );
    md_update( &md_ctx, salt, slen );
    md_finish( &md_ctx, p );

    // Compensate for boundary condition when applying mask
    //
    if( msb % 8 == 0 )
        offset = 1;

    // maskedDB: Apply dbMask to DB
    //
    mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );

    md_free_ctx( &md_ctx );

    msb = mpi_msb( &ctx->N ) - 1;
    sig[0] &= 0xFF >> ( olen * 8 - msb );

    p += hlen;
    *p++ = 0xBC;

    return( ( mode == RSA_PUBLIC )
            ? rsa_public(  ctx, sig, sig )
            : rsa_private( ctx, sig, sig ) );
}
Пример #10
0
/*
 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
 */
int rsa_rsassa_pss_verify( rsa_context *ctx,
                           int mode,
                           int hash_id,
                           unsigned int hashlen,
                           const unsigned char *hash,
                           unsigned char *sig )
{
    int ret;
    size_t siglen;
    unsigned char *p;
    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
    unsigned char result[POLARSSL_MD_MAX_SIZE];
    unsigned char zeros[8];
    unsigned int hlen;
    size_t slen, msb;
    const md_info_t *md_info;
    md_context_t md_ctx;

    if( ctx->padding != RSA_PKCS_V21 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    siglen = ctx->len;

    if( siglen < 16 || siglen > 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;

    if( buf[siglen - 1] != 0xBC )
        return( POLARSSL_ERR_RSA_INVALID_PADDING );

    switch( hash_id )
    {
        case SIG_RSA_MD2:
        case SIG_RSA_MD4:
        case SIG_RSA_MD5:
            hashlen = 16;
            break;

        case SIG_RSA_SHA1:
            hashlen = 20;
            break;

        case SIG_RSA_SHA224:
            hashlen = 28;
            break;

        case SIG_RSA_SHA256:
            hashlen = 32;
            break;

        case SIG_RSA_SHA384:
            hashlen = 48;
            break;

        case SIG_RSA_SHA512:
            hashlen = 64;
            break;

        default:
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    md_info = md_info_from_type( ctx->hash_id );
    if( md_info == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    hlen = md_get_size( md_info );
    slen = siglen - hlen - 1;

    memset( zeros, 0, 8 );

    // Note: EMSA-PSS verification is over the length of N - 1 bits
    //
    msb = mpi_msb( &ctx->N ) - 1;

    // Compensate for boundary condition when applying mask
    //
    if( msb % 8 == 0 )
    {
        p++;
        siglen -= 1;
    }
    if( buf[0] >> ( 8 - siglen * 8 + msb ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    md_init_ctx( &md_ctx, md_info );

    mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );

    buf[0] &= 0xFF >> ( siglen * 8 - msb );

    while( *p == 0 && p < buf + siglen )
        p++;

    if( p == buf + siglen ||
        *p++ != 0x01 )
    {
        md_free_ctx( &md_ctx );
        return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    slen -= p - buf;

    // Generate H = Hash( M' )
    //
    md_starts( &md_ctx );
    md_update( &md_ctx, zeros, 8 );
    md_update( &md_ctx, hash, hashlen );
    md_update( &md_ctx, p, slen );
    md_finish( &md_ctx, result );

    md_free_ctx( &md_ctx );

    if( memcmp( p + slen, result, hlen ) == 0 )
        return( 0 );
    else
        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
}
Пример #11
0
/*
 * Do an RSA operation and check the message digest
 */
int rsa_pkcs1_verify( rsa_context *ctx,
                      int mode,
                      int hash_id,
                      unsigned int hashlen,
                      const unsigned char *hash,
                      unsigned char *sig )
{
    int ret;
    size_t len, siglen;
    unsigned char *p, c;
    unsigned char buf[1024];
#if defined(POLARSSL_PKCS1_V21)
    unsigned char zeros[8];
    unsigned int hlen;
    size_t slen, msb;
    const md_info_t *md_info;
    md_context_t md_ctx;
#endif
    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++;

            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 );
            }

            break;

#if defined(POLARSSL_PKCS1_V21)
        case RSA_PKCS_V21:
            
            if( buf[siglen - 1] != 0xBC )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            switch( hash_id )
            {
                case SIG_RSA_MD2:
                case SIG_RSA_MD4:
                case SIG_RSA_MD5:
                    hashlen = 16;
                    break;

                case SIG_RSA_SHA1:
                    hashlen = 20;
                    break;

                case SIG_RSA_SHA224:
                    hashlen = 28;
                    break;

                case SIG_RSA_SHA256:
                    hashlen = 32;
                    break;

                case SIG_RSA_SHA384:
                    hashlen = 48;
                    break;

                case SIG_RSA_SHA512:
                    hashlen = 64;
                    break;

                default:
                    return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
            }

            md_info = md_info_from_type( ctx->hash_id );
            if( md_info == NULL )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
                
            hlen = md_get_size( md_info );
            slen = siglen - hlen - 1;

            memset( &md_ctx, 0, sizeof( md_context_t ) );
            memset( zeros, 0, 8 );

            md_init_ctx( &md_ctx, md_info );

            // Note: EMSA-PSS verification is over the length of N - 1 bits
            //
            msb = mpi_msb( &ctx->N ) - 1;

            // Compensate for boundary condition when applying mask
            //
            if( msb % 8 == 0 )
            {
                p++;
                siglen -= 1;
            }
            if( buf[0] >> ( 8 - siglen * 8 + msb ) )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

            mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );

            buf[0] &= 0xFF >> ( siglen * 8 - msb );

            while( *p == 0 && p < buf + siglen )
                p++;

            if( p == buf + siglen )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            if( *p++ != 0x01 )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            slen -= p - buf;

            // Generate H = Hash( M' )
            //
            md_starts( &md_ctx );
            md_update( &md_ctx, zeros, 8 );
            md_update( &md_ctx, hash, hashlen );
            md_update( &md_ctx, p, slen );
            md_finish( &md_ctx, p );

            if( memcmp( p, p + slen, hlen ) == 0 )
                return( 0 );
            else
                return( POLARSSL_ERR_RSA_VERIFY_FAILED );
            break;
#endif

        default:

            return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    return( POLARSSL_ERR_RSA_INVALID_PADDING );
}
Пример #12
0
int sign(unsigned char *output,unsigned char *input, int input_len, char *pri_key_file)
{
	unsigned char * cipher = NULL;
	unsigned char * k_c = NULL;
	unsigned char sign[128];
	int ret;
	
	FILE *fkey;
	rsa_context rsa_ctx;
	havege_state prng_ctx;
	
	cipher = (unsigned char *)malloc((32)*sizeof(char));

	/* ********************** HASH controle integrite *********************** */

	k_c = (unsigned char *)malloc(2*KEY_LENGTH*sizeof(unsigned char));
	memset(k_c, 0, 2*KEY_LENGTH);

	//generation de la clef symetrique de KEY_LENGTH bits
	gen_key(k_c, KEY_LENGTH);
	sha2_hmac(k_c, KEY_LENGTH, input, input_len, cipher, 0);

	print_hex(k_c, KEY_LENGTH, "cle secrete utilisée pour le hash : ");

	/* *** Read the private asymetric key in the file*** */
	if( ( fkey = fopen( pri_key_file, "rb" ) ) == NULL ) {		
        	ret = 1;
       		printf( " failed\n  ! Could not open %s\n" \
                "  ! Please run rsa_genkey first\n\n",pri_key_file );
        	goto cleanup;
	}

	rsa_init( &rsa_ctx, RSA_PKCS_V15, 0 );

	    if( ( ret = mpi_read_file( &rsa_ctx.N , 16, fkey ) ) != 0 ||
	        ( ret = mpi_read_file( &rsa_ctx.E , 16, fkey ) ) != 0 ||
	        ( ret = mpi_read_file( &rsa_ctx.D , 16, fkey ) ) != 0 ||
	        ( ret = mpi_read_file( &rsa_ctx.P , 16, fkey ) ) != 0 ||
	        ( ret = mpi_read_file( &rsa_ctx.Q , 16, fkey ) ) != 0 ||
	        ( ret = mpi_read_file( &rsa_ctx.DP, 16, fkey ) ) != 0 ||
	        ( ret = mpi_read_file( &rsa_ctx.DQ, 16, fkey ) ) != 0 ||
	        ( ret = mpi_read_file( &rsa_ctx.QP, 16, fkey ) ) != 0 )
	    {
	        printf( " failed\n  ! mpi_read_file returned %d\n\n", ret );
	        goto cleanup;
	    }

	    rsa_ctx.len = ( mpi_msb( &rsa_ctx.N ) + 7 ) >> 3;

	    fclose( fkey );
	
	/* *** SYM_K(key) : chiffrement RSA de la clé de chiffrement key (16) => rsa-1024 bits = 128 octets en sortie *** */
	/* *** cipher = ASYM_Kpriv (Hash) *** */
	havege_init(&prng_ctx);
	memset(sign, 0, 128);
	if( ( ret = rsa_pkcs1_encrypt( &rsa_ctx, havege_random, &prng_ctx, RSA_PRIVATE, KEY_LENGTH, cipher, sign ) ) != 0 ) {
	        printf( " failed\n  ! rsa_pkcs1_encrypt returned %d\n\n", ret );
        	goto cleanup;
	}

	print_hex(sign, sizeof(sign), "Hash chiffrée avec RSA : ");

	/* *** ASYM_Kpub (K) *** */
	output = (unsigned char *) malloc( 128 * sizeof(unsigned char));
	memcpy(output, sign, 128);

cleanup:
	if(cipher != NULL) {
		memset(cipher, 0, 32);
		free(cipher);
	}
	if(k_c != NULL) {
		memset(k_c, 0, 2*KEY_LENGTH);
		free(k_c);
	}
	memset(&prng_ctx,0x00, sizeof(havege_state));
	memset(&rsa_ctx, 0x00, sizeof(rsa_ctx));
	memset(sign, 0, 128);

	return ret;
}
Пример #13
0
int decipher_buffer(unsigned char **output, int *output_len,
                    unsigned char *input, int input_len,
                    char *priv_key_file)
{
    int offset, ret;
    size_t key_len;
    unsigned char s_key[32] = {0};
    aes_context aes_ctx;
    rsa_context rsa_ctx;
    FILE *f;

    unsigned char iv[16] = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };

    /* *** Init *** */
    ret = 1;
    offset = 0;
    key_len = 0;
    f = NULL;

    /* *** Get private key *** */
    f = fopen(priv_key_file, "rb");
    if (f == NULL) {
        fprintf(stderr, "error : unable to open %s\n", priv_key_file);
        ret = 1;
        goto cleanup;
    }
    rsa_init(&rsa_ctx, RSA_PKCS_V15, 0 );
    if (mpi_read_file(&rsa_ctx.N, 16, f) != 0
            || mpi_read_file(&rsa_ctx.E, 16, f) != 0
            || mpi_read_file(&rsa_ctx.D, 16, f) != 0
            || mpi_read_file(&rsa_ctx.P, 16, f) != 0
            || mpi_read_file(&rsa_ctx.Q, 16, f) != 0
            || mpi_read_file(&rsa_ctx.DP, 16, f) != 0
            || mpi_read_file(&rsa_ctx.DQ, 16, f) != 0
            || mpi_read_file(&rsa_ctx.QP, 16, f) != 0) {
        fprintf(stderr, "error : unable to read private key\n");
        ret = 1;
        goto cleanup;
    }
    rsa_ctx.len = (mpi_msb(&rsa_ctx.N ) + 7 ) >> 3;

    /* *** Decipher *** */
    ret = rsa_pkcs1_decrypt(&rsa_ctx, RSA_PRIVATE, &key_len,
                            input, s_key, 16);
    if (ret != 0) {
        fprintf(stderr, "error : rsa_pkcs1_decrypt failed\n");
        ret = 1;
        goto cleanup;
    }
    ret = aes_setkey_dec(&aes_ctx, s_key, 256);
    if (ret != 0) {
        fprintf(stderr, "error : aes_setkey_dec failed\n");
        ret = 1;
        goto cleanup;
    }

    /* *** Plain text *** */
    *output = (unsigned char *) malloc((input_len - 128) *
                                       sizeof(unsigned char));
    memset(*output, 0, input_len - 128);
    ret = aes_crypt_cbc(&aes_ctx, AES_DECRYPT, input_len - 128 , iv,
                        input + 128, *output);
    if (ret != 0) {
        fprintf(stderr, "error : aes_crypt_cbc failed\n");
        ret = 1;
        goto cleanup;
    }

    /* *** Padding *** */
    for (offset = input_len - 128 - 1; offset >= 0; offset--) {
        if((*output)[offset] == 0x80) {
            *output_len = offset;
            (*output)[offset] = 0x00;
            break;
        }
    }

cleanup:
    if(f != NULL)
        fclose(f);
    rsa_free(&rsa_ctx);
    return ret;
}
Пример #14
0
/**
*  Adds padding and encrypts a string using either private or public key. 
* (depending on mode).
*  @param message: arbitrary binary string to be encrypted.
*  @param keytable: table containing either the public or the private key, as generated by gen_key.
*  @return  The cyphertext (as a binary string).
*  @see  rsa_genkey
*/
static int luarsa_pkcs1_encrypt (lua_State *L) {
	int res = 0;
	int mode;
    size_t lmsg, lresult;
    rsa_context rsa;
    char *message = (char*)luaL_checklstring(L, 1, &lmsg); /* message */
    char result[KEY_SIZE];
char alt_result[KEY_SIZE];
    char* strMode=NULL;
    if(lua_type(L, 3)==LUA_TSTRING) {
        printf("Got parameter\n");
        strMode = (char*)lua_tostring(L, 3);
        printf("[%s]\n", strMode);
        mode = strncmp(strMode, "private", 7) ? RSA_PUBLIC : RSA_PRIVATE;
    }
    
    rsa_init( &rsa, RSA_PKCS_V15, 0, NULL, NULL ); 
    
    processKey(L, 2, &rsa); /* keytable */
    
    rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3;
    
    memset(result, 0, KEY_SIZE);
    
// <test> by Jason
    printf("\nMode==%s\n", mode==RSA_PUBLIC ? "RSA_PUBLIC" : "RSA_PRIVATE" );
    printf("Size==%d\n", lmsg );
    printf("Crypt.Size==%d\n", rsa.len );
    
    printf("ver: %d\n", rsa.ver);
    printf("len: %d\n", rsa.len);
    printf("padding: %d\n", rsa.padding);
    printf("hash_id: %d\n", rsa.hash_id);
    
    mpi_print("N:%s\n", &rsa.N);
    mpi_print("E:%s\n", &rsa.E);
    
    if(mode!=RSA_PUBLIC) {
        //mpi_print("D:%s\n", &rsa.D);
        //mpi_print("P:%s\n", &rsa.P);
        //mpi_print("Q:%s\n", &rsa.Q);
        //mpi_print("DP:%s\n", &rsa.DP);
        //mpi_print("DQ:%s\n", &rsa.DQ);
        //mpi_print("QP:%s\n", &rsa.QP);

        //mpi_print("RN:%s\n", &rsa.RN);
        //mpi_print("RP:%s\n", &rsa.RP);
        //mpi_print("RQ:%s\n", &rsa.RQ);
    }
// </test> by Jason

    // pass rsa context and message to encryption engine
    res = rsa_pkcs1_encrypt(&rsa, RSA_PUBLIC, lmsg, message, result);
    
    if(res)
    	luaL_error(L, "Error during cipher (%d)", res);
/*    
    lmsg = 128;
    res = rsa_pkcs1_decrypt(&rsa, mode, &lmsg, result, alt_result);
    
    if(res)
    	luaL_error(L, "Error during decipher (%d)", res);
    
    printf("(%d)", lmsg);
*/
    push_private_key(L, &rsa);
    
    // push encrypted result buffer
    lua_pushlstring(L, result, rsa.len); /* ciphertext */

    rsa_free( &rsa );
    
    return 1;
}
Пример #15
0
static int Bbits(lua_State *L)
{
    mpi *a=Bget(L,1);
    lua_pushinteger(L, mpi_msb(a));
    return 1;
}
Пример #16
0
/*
 * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
 * WARNING: the resulting group should only be used with
 * pk_group_id_from_specified(), since its base point may not be set correctly
 * if it was encoded compressed.
 *
 *  SpecifiedECDomain ::= SEQUENCE {
 *      version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
 *      fieldID FieldID {{FieldTypes}},
 *      curve Curve,
 *      base ECPoint,
 *      order INTEGER,
 *      cofactor INTEGER OPTIONAL,
 *      hash HashAlgorithm OPTIONAL,
 *      ...
 *  }
 *
 * We only support prime-field as field type, and ignore hash and cofactor.
 */
static int pk_group_from_specified( const asn1_buf *params, ecp_group *grp )
{
    int ret;
    unsigned char *p = params->p;
    const unsigned char * const end = params->p + params->len;
    const unsigned char *end_field, *end_curve;
    size_t len;
    int ver;

    /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
    if( ( ret = asn1_get_int( &p, end, &ver ) ) != 0 )
        return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );

    if( ver < 1 || ver > 3 )
        return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );

    /*
     * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
     *       fieldType FIELD-ID.&id({IOSet}),
     *       parameters FIELD-ID.&Type({IOSet}{@fieldType})
     * }
     */
    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
        return( ret );

    end_field = p + len;

    /*
     * FIELD-ID ::= TYPE-IDENTIFIER
     * FieldTypes FIELD-ID ::= {
     *       { Prime-p IDENTIFIED BY prime-field } |
     *       { Characteristic-two IDENTIFIED BY characteristic-two-field }
     * }
     * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
     */
    if( ( ret = asn1_get_tag( &p, end_field, &len, ASN1_OID ) ) != 0 )
        return( ret );

    if( len != OID_SIZE( OID_ANSI_X9_62_PRIME_FIELD ) ||
        memcmp( p, OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
    {
        return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
    }

    p += len;

    /* Prime-p ::= INTEGER -- Field of size p. */
    if( ( ret = asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 )
        return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );

    grp->pbits = mpi_msb( &grp->P );

    if( p != end_field )
        return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );

    /*
     * Curve ::= SEQUENCE {
     *       a FieldElement,
     *       b FieldElement,
     *       seed BIT STRING OPTIONAL
     *       -- Shall be present if used in SpecifiedECDomain
     *       -- with version equal to ecdpVer2 or ecdpVer3
     * }
     */
    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
        return( ret );

    end_curve = p + len;

    /*
     * FieldElement ::= OCTET STRING
     * containing an integer in the case of a prime field
     */
    if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 ||
        ( ret = mpi_read_binary( &grp->A, p, len ) ) != 0 )
    {
        return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
    }

    p += len;

    if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 ||
        ( ret = mpi_read_binary( &grp->B, p, len ) ) != 0 )
    {
        return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
    }

    p += len;

    /* Ignore seed BIT STRING OPTIONAL */
    if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_BIT_STRING ) ) == 0 )
        p += len;

    if( p != end_curve )
        return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );

    /*
     * ECPoint ::= OCTET STRING
     */
    if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
        return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );

    if( ( ret = ecp_point_read_binary( grp, &grp->G,
                                      ( const unsigned char *) p, len ) ) != 0 )
    {
        /*
         * If we can't read the point because it's compressed, cheat by
         * reading only the X coordinate and the parity bit of Y.
         */
        if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ||
            ( p[0] != 0x02 && p[0] != 0x03 ) ||
            len != mpi_size( &grp->P ) + 1 ||
            mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 ||
            mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 ||
            mpi_lset( &grp->G.Z, 1 ) != 0 )
        {
            return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
        }
    }

    p += len;

    /*
     * order INTEGER
     */
    if( ( ret = asn1_get_mpi( &p, end, &grp->N ) ) != 0 )
        return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );

    grp->nbits = mpi_msb( &grp->N );

    /*
     * Allow optional elements by purposefully not enforcing p == end here.
     */

    return( 0 );
}
Пример #17
0
int main( int argc, char *argv[] )
{
    FILE *f;
    int ret, i;
    rsa_context rsa;
    unsigned char hash[20];
    unsigned char buf[512];

    ret = 1;

    if( argc != 2 )
    {
        printf( "usage: rsa_sign <filename>\n" );

#ifdef WIN32
        printf( "\n" );
#endif

        goto exit;
    }

    printf( "\n  . Reading private key from rsa_priv.txt" );
    fflush( stdout );

    if( ( f = fopen( "rsa_priv.txt", "rb" ) ) == NULL )
    {
        ret = 1;
        printf( " failed\n  ! Could not open rsa_priv.txt\n" \
                "  ! Please run rsa_genkey first\n\n" );
        goto exit;
    }

    rsa_init( &rsa, RSA_PKCS_V15, 0, NULL, NULL );
    
    if( ( ret = mpi_read_file( &rsa.N , 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.E , 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.D , 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.P , 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.Q , 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.DP, 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.DQ, 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.QP, 16, f ) ) != 0 )
    {
        printf( " failed\n  ! mpi_read_file returned %d\n\n", ret );
        goto exit;
    }

    rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3;

    fclose( f );

    /*
     * Compute the SHA-1 hash of the input file,
     * then calculate the RSA signature of the hash.
     */
    printf( "\n  . Generating the RSA/SHA-1 signature" );
    fflush( stdout );

    if( ( ret = sha1_file( argv[1], hash ) ) != 0 )
    {
        printf( " failed\n  ! Could not open or read %s\n\n", argv[1] );
        goto exit;
    }

    if( ( ret = rsa_pkcs1_sign( &rsa, RSA_PRIVATE, SIG_RSA_SHA1,
                                20, hash, buf ) ) != 0 )
    {
        printf( " failed\n  ! rsa_pkcs1_sign returned %d\n\n", ret );
        goto exit;
    }

    /*
     * Write the signature into <filename>-sig.txt
     */
    memcpy( argv[1] + strlen( argv[1] ), ".sig", 5 );

    if( ( f = fopen( argv[1], "wb+" ) ) == NULL )
    {
        ret = 1;
        printf( " failed\n  ! Could not create %s\n\n", argv[1] );
        goto exit;
    }

    for( i = 0; i < rsa.len; i++ )
        fprintf( f, "%02X%s", buf[i],
                 ( i + 1 ) % 16 == 0 ? "\r\n" : " " );

    fclose( f );

    printf( "\n  . Done (created \"%s\")\n\n", argv[1] );

exit:

#ifdef WIN32
    printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( ret );
}
Пример #18
0
int main( int argc, char *argv[] )
{
    FILE *f;
    int ret, c;
    size_t i;
    rsa_context rsa;
    entropy_context entropy;
    ctr_drbg_context ctr_drbg;
    unsigned char result[1024];
    unsigned char buf[512];
    const char *pers = "rsa_decrypt";
    ((void) argv);

    memset(result, 0, sizeof( result ) );
    ret = 1;

    if( argc != 1 )
    {
        polarssl_printf( "usage: rsa_decrypt\n" );

#if defined(_WIN32)
        polarssl_printf( "\n" );
#endif

        goto exit;
    }

    polarssl_printf( "\n  . Seeding the random number generator..." );
    fflush( stdout );

    entropy_init( &entropy );
    if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
                               (const unsigned char *) pers,
                               strlen( pers ) ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! ctr_drbg_init returned %d\n", ret );
        goto exit;
    }

    polarssl_printf( "\n  . Reading private key from rsa_priv.txt" );
    fflush( stdout );

    if( ( f = fopen( "rsa_priv.txt", "rb" ) ) == NULL )
    {
        polarssl_printf( " failed\n  ! Could not open rsa_priv.txt\n" \
                "  ! Please run rsa_genkey first\n\n" );
        goto exit;
    }

    rsa_init( &rsa, RSA_PKCS_V15, 0 );

    if( ( ret = mpi_read_file( &rsa.N , 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.E , 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.D , 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.P , 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.Q , 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.DP, 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.DQ, 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.QP, 16, f ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! mpi_read_file returned %d\n\n", ret );
        goto exit;
    }

    rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3;

    fclose( f );

    /*
     * Extract the RSA encrypted value from the text file
     */
    ret = 1;

    if( ( f = fopen( "result-enc.txt", "rb" ) ) == NULL )
    {
        polarssl_printf( "\n  ! Could not open %s\n\n", "result-enc.txt" );
        goto exit;
    }

    i = 0;

    while( fscanf( f, "%02X", &c ) > 0 &&
           i < (int) sizeof( buf ) )
        buf[i++] = (unsigned char) c;

    fclose( f );

    if( i != rsa.len )
    {
        polarssl_printf( "\n  ! Invalid RSA signature format\n\n" );
        goto exit;
    }

    /*
     * Decrypt the encrypted RSA data and print the result.
     */
    polarssl_printf( "\n  . Decrypting the encrypted data" );
    fflush( stdout );

    if( ( ret = rsa_pkcs1_decrypt( &rsa, ctr_drbg_random, &ctr_drbg,
                                   RSA_PRIVATE, &i, buf, result,
                                   1024 ) ) != 0 )
    {
        polarssl_printf( " failed\n  ! rsa_pkcs1_decrypt returned %d\n\n", ret );
        goto exit;
    }

    polarssl_printf( "\n  . OK\n\n" );

    polarssl_printf( "The decrypted result is: '%s'\n\n", result );

    ret = 0;

exit:
    ctr_drbg_free( &ctr_drbg );
    entropy_free( &entropy );

#if defined(_WIN32)
    polarssl_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( ret );
}
Пример #19
0
int main( int argc, char *argv[] )
{
    FILE *f;
    int ret, i, c;
    rsa_context rsa;
    unsigned char hash[20];
    unsigned char buf[512];

    ret = 1;
    if( argc != 2 )
    {
        printf( "usage: rsa_verify <filename>\n" );

#ifdef WIN32
        printf( "\n" );
#endif

        goto exit;
    }

    printf( "\n  . Reading public key from rsa_pub.txt" );
    fflush( stdout );

    if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL )
    {
        printf( " failed\n  ! Could not open rsa_pub.txt\n" \
                "  ! Please run rsa_genkey first\n\n" );
        goto exit;
    }

    rsa_init( &rsa, RSA_PKCS_V15, 0, NULL, NULL );

    if( ( ret = mpi_read_file( &rsa.N, 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.E, 16, f ) ) != 0 )
    {
        printf( " failed\n  ! mpi_read_file returned %d\n\n", ret );
        goto exit;
    }

    rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3;

    fclose( f );

    /*
     * Extract the RSA signature from the text file
     */
    ret = 1;
    i = strlen( argv[1] );
    memcpy( argv[1] + i, ".sig", 5 );

    if( ( f = fopen( argv[1], "rb" ) ) == NULL )
    {
        printf( "\n  ! Could not open %s\n\n", argv[1] );
        goto exit;
    }

    argv[1][i] = '\0', i = 0;

    while( fscanf( f, "%02X", &c ) > 0 &&
           i < (int) sizeof( buf ) )
        buf[i++] = (unsigned char) c;

    fclose( f );

    if( i != rsa.len )
    {
        printf( "\n  ! Invalid RSA signature format\n\n" );
        goto exit;
    }

    /*
     * Compute the SHA-1 hash of the input file and compare
     * it with the hash decrypted from the RSA signature.
     */
    printf( "\n  . Verifying the RSA/SHA-1 signature" );
    fflush( stdout );

    if( ( ret = sha1_file( argv[1], hash ) ) != 0 )
    {
        printf( " failed\n  ! Could not open or read %s\n\n", argv[1] );
        goto exit;
    }

    if( ( ret = rsa_pkcs1_verify( &rsa, RSA_PUBLIC, RSA_SHA1,
                                  20, hash, buf ) ) != 0 )
    {
        printf( " failed\n  ! rsa_pkcs1_verify returned %d\n\n", ret );
        goto exit;
    }

    printf( "\n  . OK (the decrypted SHA-1 hash matches)\n\n" );

    ret = 0;

exit:

#ifdef WIN32
    printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( ret );
}
Пример #20
0
/*
 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
 */
int rsa_rsassa_pss_verify_ext( rsa_context *ctx,
                               int (*f_rng)(void *, unsigned char *, size_t),
                               void *p_rng,
                               int mode,
                               md_type_t md_alg,
                               unsigned int hashlen,
                               const unsigned char *hash,
                               md_type_t mgf1_hash_id,
                               int expected_salt_len,
                               const unsigned char *sig )
{
    int ret;
    size_t siglen;
    unsigned char *p;
    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
    unsigned char result[POLARSSL_MD_MAX_SIZE];
    unsigned char zeros[8];
    unsigned int hlen;
    size_t slen, msb;
    const md_info_t *md_info;
    md_context_t md_ctx;

    if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    siglen = ctx->len;

    if( siglen < 16 || siglen > sizeof( buf ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ret = ( mode == RSA_PUBLIC )
          ? rsa_public(  ctx, sig, buf )
          : rsa_private( ctx, f_rng, p_rng, sig, buf );

    if( ret != 0 )
        return( ret );

    p = buf;

    if( buf[siglen - 1] != 0xBC )
        return( POLARSSL_ERR_RSA_INVALID_PADDING );

    if( md_alg != POLARSSL_MD_NONE )
    {
        // Gather length of hash to sign
        //
        md_info = md_info_from_type( md_alg );
        if( md_info == NULL )
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

        hashlen = md_get_size( md_info );
    }

    md_info = md_info_from_type( mgf1_hash_id );
    if( md_info == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    hlen = md_get_size( md_info );
    slen = siglen - hlen - 1; /* Currently length of salt + padding */

    memset( zeros, 0, 8 );

    // Note: EMSA-PSS verification is over the length of N - 1 bits
    //
    msb = mpi_msb( &ctx->N ) - 1;

    // Compensate for boundary condition when applying mask
    //
    if( msb % 8 == 0 )
    {
        p++;
        siglen -= 1;
    }
    if( buf[0] >> ( 8 - siglen * 8 + msb ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    md_init( &md_ctx );
    md_init_ctx( &md_ctx, md_info );

    mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );

    buf[0] &= 0xFF >> ( siglen * 8 - msb );

    while( p < buf + siglen && *p == 0 )
        p++;

    if( p == buf + siglen ||
        *p++ != 0x01 )
    {
        md_free( &md_ctx );
        return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    /* Actual salt len */
    slen -= p - buf;

    if( expected_salt_len != RSA_SALT_LEN_ANY &&
        slen != (size_t) expected_salt_len )
    {
        md_free( &md_ctx );
        return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    // Generate H = Hash( M' )
    //
    md_starts( &md_ctx );
    md_update( &md_ctx, zeros, 8 );
    md_update( &md_ctx, hash, hashlen );
    md_update( &md_ctx, p, slen );
    md_finish( &md_ctx, result );

    md_free( &md_ctx );

    if( memcmp( p + slen, result, hlen ) == 0 )
        return( 0 );
    else
        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
}
Пример #21
0
int main( int argc, char *argv[] )
{
    FILE *f;

    int ret;
    size_t n, buflen;
    int server_fd = -1;

    unsigned char *p, *end;
    unsigned char buf[2048];
    unsigned char hash[20];
    const char *pers = "dh_client";

    entropy_context entropy;
    ctr_drbg_context ctr_drbg;
    rsa_context rsa;
    dhm_context dhm;
    aes_context aes;

    ((void) argc);
    ((void) argv);

    memset( &rsa, 0, sizeof( rsa ) );
    memset( &dhm, 0, sizeof( dhm ) );

    /*
     * 1. Setup the RNG
     */
    printf( "\n  . Seeding the random number generator" );
    fflush( stdout );

    entropy_init( &entropy );
    if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
                               (const unsigned char *) pers,
                               strlen( pers ) ) ) != 0 )
    {
        printf( " failed\n  ! ctr_drbg_init returned %d\n", ret );
        goto exit;
    }

    /*
     * 2. Read the server's public RSA key
     */
    printf( "\n  . Reading public key from rsa_pub.txt" );
    fflush( stdout );

    if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL )
    {
        ret = 1;
        printf( " failed\n  ! Could not open rsa_pub.txt\n" \
                "  ! Please run rsa_genkey first\n\n" );
        goto exit;
    }

    rsa_init( &rsa, RSA_PKCS_V15, 0 );

    if( ( ret = mpi_read_file( &rsa.N, 16, f ) ) != 0 ||
        ( ret = mpi_read_file( &rsa.E, 16, f ) ) != 0 )
    {
        printf( " failed\n  ! mpi_read_file returned %d\n\n", ret );
        goto exit;
    }

    rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3;

    fclose( f );

    /*
     * 3. Initiate the connection
     */
    printf( "\n  . Connecting to tcp/%s/%d", SERVER_NAME,
                                             SERVER_PORT );
    fflush( stdout );

    if( ( ret = net_connect( &server_fd, SERVER_NAME,
                                         SERVER_PORT ) ) != 0 )
    {
        printf( " failed\n  ! net_connect returned %d\n\n", ret );
        goto exit;
    }

    /*
     * 4a. First get the buffer length
     */
    printf( "\n  . Receiving the server's DH parameters" );
    fflush( stdout );

    memset( buf, 0, sizeof( buf ) );

    if( ( ret = net_recv( &server_fd, buf, 2 ) ) != 2 )
    {
        printf( " failed\n  ! net_recv returned %d\n\n", ret );
        goto exit;
    }

    n = buflen = ( buf[0] << 8 ) | buf[1];
    if( buflen < 1 || buflen > sizeof( buf ) )
    {
        printf( " failed\n  ! Got an invalid buffer length\n\n" );
        goto exit;
    }

    /*
     * 4b. Get the DHM parameters: P, G and Ys = G^Xs mod P
     */
    memset( buf, 0, sizeof( buf ) );

    if( ( ret = net_recv( &server_fd, buf, n ) ) != (int) n )
    {
        printf( " failed\n  ! net_recv returned %d\n\n", ret );
        goto exit;
    }

    p = buf, end = buf + buflen;

    if( ( ret = dhm_read_params( &dhm, &p, end ) ) != 0 )
    {
        printf( " failed\n  ! dhm_read_params returned %d\n\n", ret );
        goto exit;
    }

    if( dhm.len < 64 || dhm.len > 512 )
    {
        ret = 1;
        printf( " failed\n  ! Invalid DHM modulus size\n\n" );
        goto exit;
    }

    /*
     * 5. Check that the server's RSA signature matches
     *    the SHA-1 hash of (P,G,Ys)
     */
    printf( "\n  . Verifying the server's RSA signature" );
    fflush( stdout );

    p += 2;

    if( ( n = (size_t) ( end - p ) ) != rsa.len )
    {
        ret = 1;
        printf( " failed\n  ! Invalid RSA signature size\n\n" );
        goto exit;
    }

    sha1( buf, (int)( p - 2 - buf ), hash );

    if( ( ret = rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1,
                                  0, hash, p ) ) != 0 )
    {
        printf( " failed\n  ! rsa_pkcs1_verify returned %d\n\n", ret );
        goto exit;
    }

    /*
     * 6. Send our public value: Yc = G ^ Xc mod P
     */
    printf( "\n  . Sending own public value to server" );
    fflush( stdout );

    n = dhm.len;
    if( ( ret = dhm_make_public( &dhm, dhm.len, buf, n,
                                 ctr_drbg_random, &ctr_drbg ) ) != 0 )
    {
        printf( " failed\n  ! dhm_make_public returned %d\n\n", ret );
        goto exit;
    }

    if( ( ret = net_send( &server_fd, buf, n ) ) != (int) n )
    {
        printf( " failed\n  ! net_send returned %d\n\n", ret );
        goto exit;
    }

    /*
     * 7. Derive the shared secret: K = Ys ^ Xc mod P
     */
    printf( "\n  . Shared secret: " );
    fflush( stdout );

    n = dhm.len;
    if( ( ret = dhm_calc_secret( &dhm, buf, &n ) ) != 0 )
    {
        printf( " failed\n  ! dhm_calc_secret returned %d\n\n", ret );
        goto exit;
    }

    for( n = 0; n < 16; n++ )
        printf( "%02x", buf[n] );

    /*
     * 8. Setup the AES-256 decryption key
     *
     * This is an overly simplified example; best practice is
     * to hash the shared secret with a random value to derive
     * the keying material for the encryption/decryption keys,
     * IVs and MACs.
     */
    printf( "...\n  . Receiving and decrypting the ciphertext" );
    fflush( stdout );

    aes_setkey_dec( &aes, buf, 256 );

    memset( buf, 0, sizeof( buf ) );

    if( ( ret = net_recv( &server_fd, buf, 16 ) ) != 16 )
    {
        printf( " failed\n  ! net_recv returned %d\n\n", ret );
        goto exit;
    }

    aes_crypt_ecb( &aes, AES_DECRYPT, buf, buf );
    buf[16] = '\0';
    printf( "\n  . Plaintext is \"%s\"\n\n", (char *) buf );

exit:

    net_close( server_fd );
    rsa_free( &rsa );
    dhm_free( &dhm );

#if defined(_WIN32)
    printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( ret );
}
Пример #22
0
/*
 * Do an RSA operation to sign the message digest
 */
int rsa_pkcs1_sign( rsa_context *ctx,
                    int (*f_rng)(void *),
                    void *p_rng,
                    int mode,
                    int hash_id,
                    unsigned int hashlen,
                    const unsigned char *hash,
                    unsigned char *sig )
{
    size_t nb_pad, olen;
    unsigned char *p = sig;
#if defined(POLARSSL_PKCS1_V21)
    unsigned char salt[POLARSSL_MD_MAX_SIZE];
    unsigned int i, slen, hlen, offset = 0;
    size_t msb;
    const md_info_t *md_info;
    md_context_t md_ctx;
#else
    (void) f_rng;
    (void) p_rng;
#endif

    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;

            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 );
            }

            break;

#if defined(POLARSSL_PKCS1_V21)
        case RSA_PKCS_V21:

            if( f_rng == NULL )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

            switch( hash_id )
            {
                case SIG_RSA_MD2:
                case SIG_RSA_MD4:
                case SIG_RSA_MD5:
                    hashlen = 16;
                    break;

                case SIG_RSA_SHA1:
                    hashlen = 20;
                    break;

                case SIG_RSA_SHA224:
                    hashlen = 28;
                    break;

                case SIG_RSA_SHA256:
                    hashlen = 32;
                    break;

                case SIG_RSA_SHA384:
                    hashlen = 48;
                    break;

                case SIG_RSA_SHA512:
                    hashlen = 64;
                    break;

                default:
                    return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
            }

            md_info = md_info_from_type( ctx->hash_id );
            if( md_info == NULL )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
                
            hlen = md_get_size( md_info );
            slen = hlen;

            memset( sig, 0, olen );
            memset( &md_ctx, 0, sizeof( md_context_t ) );

            md_init_ctx( &md_ctx, md_info );

            msb = mpi_msb( &ctx->N ) - 1;

            // Generate salt of length slen
            //
            for( i = 0; i < slen; ++i )
                salt[i] = (unsigned char) f_rng( p_rng ); 

            // Note: EMSA-PSS encoding is over the length of N - 1 bits
            //
            msb = mpi_msb( &ctx->N ) - 1;
            p += olen - hlen * 2 - 2;
            *p++ = 0x01;
            memcpy( p, salt, slen );
            p += slen;

            // Generate H = Hash( M' )
            //
            md_starts( &md_ctx );
            md_update( &md_ctx, p, 8 );
            md_update( &md_ctx, hash, hashlen );
            md_update( &md_ctx, salt, slen );
            md_finish( &md_ctx, p );

            // Compensate for boundary condition when applying mask
            //
            if( msb % 8 == 0 )
                offset = 1;

            // maskedDB: Apply dbMask to DB
            //
            mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );

            msb = mpi_msb( &ctx->N ) - 1;
            sig[0] &= 0xFF >> ( olen * 8 - msb );

            p += hlen;
            *p++ = 0xBC;
            break;
#endif

        default:

            return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    return( ( mode == RSA_PUBLIC )
            ? rsa_public(  ctx, sig, sig )
            : rsa_private( ctx, sig, sig ) );
}