[BCRYPT][BCRYPT_WINETEST] Sync to WineStaging-10.6 (#8267)

Sync bcrypt/bcrypt winetest with latest wine. Implement all functionality with mbedtls. DSA is my implementation based on libtomcrypt implementation as mbedtls does not support DSA. All failing tests are wine_todo

* [BCRYPT] Split implementations in different files. Add internal header. Add precompiled header. These changes are needed to make bcrypt more wine compatible

* [BCRYPT] Update to latest bcrypt from wine. Add their gnutls implementation with small changes. Add missing function in the other implementations returning STATUS_NOT_IMPLEMENTED. WARNING! gnutls is modified just visually and is n ot compiled locally as we don't have gnutls in ReactOS for a long time and we depend on mbedtls implementation.

* [BCRYPT] Remove forgotten code. Remove hmac BOOL and use hash->flags for hmac

* [BCRYPT] Remove some dead code. Move flag defines in header. Use constant for flag

* [BCRYPT][WINETEST] Update bcrypt wine test to current version. On windows it executes 23114 tests successfully

* [MBEDTLS] Activate MD2 and MD4 hashing algorithms

* [MBEDTLS] Export additional MD functions

* [BCRYPT][WINETEST] Disable not implemented method tests

* [BCRYPT] Remove unneeded headers

* [BCRYPT] Fix some struct variables and add a hash method

* [BCRYPT] Update common crypto implementation

* [MBEDTLS] Expose AES CFB8

* [MBEDTLS] Export simetric encryption/decryption functions

* [BCRYPT] Implement symetric encryption/decryption

* [BCRYPT][WINETEST] Activate symetric encryption/decryption tests. From 22541 Only 3 fail on wine_todo

* [BCRYPT][WINETEST] Disable pbkdf tests. They crash calling function with ULONGLONG parameter

* [MBEDTLS] Export additional functions

* [BCRYPT] Expand private data size

* [BCRYPT] Implement asymetric encryption/decryption. NOTE: DSA is NOT supported by mbedtls, so it is not implemented here

* [MBEDTLS] Disable range check for mbedtls_dhm_calc_secret for ReactOS. It fails tests for key derivation

* [BCRYPT][WINETEST] Enable all tests

* [BCRYPT] Update exports

* [MBEDTLS] Add DSA implementation. It is my implementation based on libtomcrypt and adapted to mbedtls. It is NOT part of mbedtls!

* [BCRYPT] Implement DSA encryption/decryption. Use union for cipher/pk/dh/dsa keys to lower memory used for a key. Lower PRIVATE_DATA_SIZE accordingly.

* [BCRYPT] Fix missed cleanup on error paths. Fixed missed DSA key reinitialization. Change some error codes to STATUS_NO_MEMORY. Minor formatting

* [WINESYNC] Update bcrypt sync status

* [MBEDTLS] Fix double export and move an export for readability

* [BCRYPT] Enable ARC4 (RC4) algorithm

* [BCRYPT] Extend private data size to fit x64

* [WINESYNC] Update WINESYNC.txt to exclude commit hash

---------

Co-authored-by: Justin Miller <justin.miller@reactos.org>
This commit is contained in:
Hater
2026-08-30 04:29:51 +03:00
committed by GitHub
parent 599870dd12
commit 340f6cfec4
19 changed files with 14278 additions and 1532 deletions

View File

@@ -27,6 +27,7 @@ list(APPEND SOURCE
#debug.c
des.c
dhm.c
dsa.c
ecdh.c
ecdsa.c
ecp.c
@@ -38,8 +39,8 @@ list(APPEND SOURCE
#havege.c
#hkdf.c
hmac_drbg.c
#md2.c
#md4.c
md2.c
md4.c
md5.c
md.c
md_wrap.c

View File

@@ -173,6 +173,15 @@ static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv,
input, output );
}
#ifdef __REACTOS__
static int aes_crypt_cfb8_wrap( void *ctx, mbedtls_operation_t operation,
size_t length, size_t *iv_off, unsigned char *iv,
const unsigned char *input, unsigned char *output )
{
return mbedtls_aes_crypt_cfb8( (mbedtls_aes_context *) ctx, operation, length, iv,
input, output );
}
#endif
#endif /* MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_OFB)
@@ -278,6 +287,35 @@ static const mbedtls_cipher_base_t aes_info = {
aes_ctx_free
};
#ifdef __REACTOS__
static const mbedtls_cipher_base_t cfb8_aes_info = {
MBEDTLS_CIPHER_ID_AES,
aes_crypt_ecb_wrap,
#if defined(MBEDTLS_CIPHER_MODE_CBC)
aes_crypt_cbc_wrap,
#endif
#if defined(MBEDTLS_CIPHER_MODE_CFB)
aes_crypt_cfb8_wrap,
#endif
#if defined(MBEDTLS_CIPHER_MODE_OFB)
aes_crypt_ofb_wrap,
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
aes_crypt_ctr_wrap,
#endif
#if defined(MBEDTLS_CIPHER_MODE_XTS)
NULL,
#endif
#if defined(MBEDTLS_CIPHER_MODE_STREAM)
NULL,
#endif
aes_setkey_enc_wrap,
aes_setkey_dec_wrap,
aes_ctx_alloc,
aes_ctx_free
};
#endif
static const mbedtls_cipher_info_t aes_128_ecb_info = {
MBEDTLS_CIPHER_AES_128_ECB,
MBEDTLS_MODE_ECB,
@@ -347,6 +385,41 @@ static const mbedtls_cipher_info_t aes_256_cbc_info = {
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
#ifdef __REACTOS__
static const mbedtls_cipher_info_t aes_128_cfb8_info = {
MBEDTLS_CIPHER_AES_128_CFB8,
MBEDTLS_MODE_CFB,
128,
"AES-128-CFB8",
16,
0,
16,
&cfb8_aes_info
};
static const mbedtls_cipher_info_t aes_192_cfb8_info = {
MBEDTLS_CIPHER_AES_192_CFB8,
MBEDTLS_MODE_CFB,
192,
"AES-192-CFB8",
16,
0,
16,
&cfb8_aes_info
};
static const mbedtls_cipher_info_t aes_256_cfb8_info = {
MBEDTLS_CIPHER_AES_256_CFB8,
MBEDTLS_MODE_CFB,
256,
"AES-256-CFB8",
16,
0,
16,
&cfb8_aes_info
};
#endif
static const mbedtls_cipher_info_t aes_128_cfb128_info = {
MBEDTLS_CIPHER_AES_128_CFB128,
MBEDTLS_MODE_CFB,
@@ -2156,6 +2229,11 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
{ MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info },
#endif
#if defined(MBEDTLS_CIPHER_MODE_CFB)
#ifdef __REACTOS__
{ MBEDTLS_CIPHER_AES_128_CFB8, &aes_128_cfb8_info },
{ MBEDTLS_CIPHER_AES_192_CFB8, &aes_192_cfb8_info },
{ MBEDTLS_CIPHER_AES_256_CFB8, &aes_256_cfb8_info },
#endif
{ MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info },
{ MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info },
{ MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info },

View File

@@ -452,9 +452,10 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
if( output_size < ctx->len )
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
#ifndef __REACTOS__
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
return( ret );
#endif
mbedtls_mpi_init( &GYb );
/* Blind peer's value */

786
dll/3rdparty/mbedtls/dsa.c vendored Normal file
View File

@@ -0,0 +1,786 @@
/*
* Digital Signature Algorithm (DSA)
*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_DSA_C)
#include "mbedtls/dsa.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/platform_util.h"
#include <string.h>
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#include <stdio.h>
#define mbedtls_printf printf
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#if !defined(MBEDTLS_DSA_ALT)
#define DSA_VALIDATE_RET( cond ) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DSA_BAD_INPUT_DATA )
#define DSA_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
/*
* Initialize context
*/
void mbedtls_dsa_init( mbedtls_dsa_context *ctx )
{
DSA_VALIDATE( ctx != NULL );
memset( ctx, 0, sizeof( mbedtls_dsa_context ) );
mbedtls_mpi_init( &ctx->P );
mbedtls_mpi_init( &ctx->Q );
mbedtls_mpi_init( &ctx->G );
mbedtls_mpi_init( &ctx->Y );
mbedtls_mpi_init( &ctx->X );
}
/*
* Free context
*/
void mbedtls_dsa_free( mbedtls_dsa_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_mpi_free( &ctx->P );
mbedtls_mpi_free( &ctx->Q );
mbedtls_mpi_free( &ctx->G );
mbedtls_mpi_free( &ctx->Y );
mbedtls_mpi_free( &ctx->X );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dsa_context ) );
}
/*
* Set group parameters
*/
int mbedtls_dsa_set_group( mbedtls_dsa_context *ctx, const mbedtls_mpi *P, const mbedtls_mpi *Q, const mbedtls_mpi *G )
{
int ret;
DSA_VALIDATE_RET( ctx != NULL );
DSA_VALIDATE_RET( P != NULL );
DSA_VALIDATE_RET( Q != NULL );
DSA_VALIDATE_RET( G != NULL );
if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 )
{
return( MBEDTLS_ERR_DSA_BAD_INPUT_DATA + ret );
}
if( ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 )
{
return( MBEDTLS_ERR_DSA_BAD_INPUT_DATA + ret );
}
if( ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
{
return( MBEDTLS_ERR_DSA_BAD_INPUT_DATA + ret );
}
if (!ctx->len) ctx->len = mbedtls_mpi_size( &ctx->P );
return( 0 );
}
/**
* Compute a power of two
* @param a The integer to store the power in
* @param n The power of two you want to store (a = 2^n)
* @return 0 on success
*/
int mpi_2expt(mbedtls_mpi *a, int n)
{
int ret;
DSA_VALIDATE_RET( a != NULL );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset(a, 0) );
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit(a, n, 1) );
cleanup:
return ret;
}
/*
* Generate keypair
*/
int mbedtls_dsa_genkey( mbedtls_dsa_context *ctx, size_t group_size, size_t modulus_size,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
int ret;
unsigned long L, N, n, outbytes, seedbytes, counter, j, i;
int mr_tests_q, mr_tests_p, found_p, found_q;
mbedtls_mpi t2L1, t2N1, t2seedlen, U, U1, W, W1, X, q, q1, p, p1, e, h, h1, g, c, t2q, seedinc, seedinc1;
unsigned char *wbuf, *sbuf, digest[MBEDTLS_DSA_MAX_GROUP];
const mbedtls_md_info_t * md_info;
DSA_VALIDATE_RET( ctx != NULL );
DSA_VALIDATE_RET( f_rng != NULL );
/* check size */
DSA_VALIDATE_RET( group_size <= MBEDTLS_DSA_MAX_GROUP );
DSA_VALIDATE_RET( group_size >= 1 );
DSA_VALIDATE_RET( group_size < modulus_size );
DSA_VALIDATE_RET( modulus_size <= MBEDTLS_DSA_MAX_MODULUS );
#if !defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA256_C)
return MBEDTLS_ERR_DSA_BAD_INPUT_DATA;
#endif
#if defined(MBEDTLS_SHA512_C)
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
#else
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
#endif
seedbytes = group_size;
L = modulus_size * 8;
N = group_size * 8;
if (N > mbedtls_md_get_size(md_info) * 8) return MBEDTLS_ERR_DSA_BAD_INPUT_DATA; /* group_size too big */
outbytes = mbedtls_md_get_size(md_info);
n = ((L + outbytes*8 - 1) / (outbytes*8)) - 1;
if ((wbuf = mbedtls_calloc(1, (n+1)*outbytes)) == NULL) { ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; goto cleanup3; }
if ((sbuf = mbedtls_calloc(1, seedbytes)) == NULL) { ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; goto cleanup2; }
mbedtls_mpi_init( &t2L1 );
mbedtls_mpi_init( &t2N1 );
mbedtls_mpi_init( &t2seedlen );
mbedtls_mpi_init( &U );
mbedtls_mpi_init( &U1 );
mbedtls_mpi_init( &W );
mbedtls_mpi_init( &W1 );
mbedtls_mpi_init( &X );
mbedtls_mpi_init( &q );
mbedtls_mpi_init( &q1 );
mbedtls_mpi_init( &p );
mbedtls_mpi_init( &p1 );
mbedtls_mpi_init( &e );
mbedtls_mpi_init( &h );
mbedtls_mpi_init( &h1 );
mbedtls_mpi_init( &g );
mbedtls_mpi_init( &c );
mbedtls_mpi_init( &t2q );
mbedtls_mpi_init( &seedinc );
mbedtls_mpi_init( &seedinc1 );
/* M-R tests (without Lucas test) according FIPS-186-4 - Appendix C.3 - table C.1 */
if (L <= 1024) { mr_tests_p = 40; }
else if (L <= 2048) { mr_tests_p = 56; }
else { mr_tests_p = 64; }
if (N <= 160) { mr_tests_q = 40; }
else if (N <= 224) { mr_tests_q = 56; }
else { mr_tests_q = 64; }
/* t2L1 = 2^(L-1) */
MBEDTLS_MPI_CHK( mpi_2expt(&t2L1, L-1) );
/* t2N1 = 2^(N-1) */
MBEDTLS_MPI_CHK( mpi_2expt(&t2N1, N-1) );
/* t2seedlen = 2^seedlen */
MBEDTLS_MPI_CHK( mpi_2expt(&t2seedlen, seedbytes*8) );
/* FIPS-186-4 A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
*
* L = The desired length of the prime p (in bits e.g. L = 1024)
* N = The desired length of the prime q (in bits e.g. N = 160)
* seedlen = The desired bit length of the domain parameter seed; seedlen shallbe equal to or greater than N
* outlen = The bit length of Hash function
*
* 1. Check that the (L, N)
* 2. If (seedlen <N), then return INVALID.
* 3. n = ceil(L / outlen) - 1
* 4. b = L- 1 - (n * outlen)
* 5. domain_parameter_seed = an arbitrary sequence of seedlen bits
* 6. U = Hash (domain_parameter_seed) mod 2^(N-1)
* 7. q = 2^(N-1) + U + 1 - (U mod 2)
* 8. Test whether or not q is prime as specified in Appendix C.3
* 9. If qis not a prime, then go to step 5.
* 10. offset = 1
* 11. For counter = 0 to (4L- 1) do {
* For j=0 to n do {
* Vj = Hash ((domain_parameter_seed+ offset + j) mod 2^seedlen
* }
* W = V0 + (V1 *2^outlen) + ... + (Vn-1 * 2^((n-1) * outlen)) + ((Vn mod 2^b) * 2^(n * outlen))
* X = W + 2^(L-1) Comment: 0 <= W < 2^(L-1); hence 2^(L-1) <= X < 2^L
* c = X mod 2*q
* p = X - (c - 1) Comment: p ~ 1 (mod 2*q)
* If (p >= 2^(L-1)) {
* Test whether or not p is prime as specified in Appendix C.3.
* If p is determined to be prime, then return VALID and the values of p, qand (optionally) the values of domain_parameter_seed and counter
* }
* offset = offset + n + 1 Comment: Increment offset
* }
*/
for(found_p=0; !found_p;) {
/* q */
for(found_q=0; !found_q;) {
f_rng( p_rng, sbuf, seedbytes );
i = outbytes;
MBEDTLS_MPI_CHK( mbedtls_md(md_info, sbuf, seedbytes, digest) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(&U, digest, outbytes) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(&U1, &U, &t2N1) );
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi(&q, &t2N1, &U1) );
if (mbedtls_mpi_get_bit(&q, 0) == 0)
{
MBEDTLS_MPI_CHK( mbedtls_mpi_copy(&q, &q1) );
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(&q, &q1, 1) );
}
if( mbedtls_mpi_is_prime_ext(&q, mr_tests_q, f_rng, p_rng) == 0) found_q = 1;
}
/* p */
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(&seedinc, sbuf, seedbytes) );
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi(&t2q, &q, &q) );
for(counter=0; counter < 4*L && !found_p; counter++) {
for(j=0; j<=n; j++) {
MBEDTLS_MPI_CHK( mbedtls_mpi_copy(&seedinc1, &seedinc) );
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(&seedinc, &seedinc1, 1) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(&seedinc1, &seedinc, &t2seedlen) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy(&seedinc, &seedinc1) );
/* seedinc = (seedinc+1) % 2^seed_bitlen */
i = mbedtls_mpi_size(&seedinc);
if (i > seedbytes) { ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA; goto cleanup; }
mbedtls_platform_zeroize(sbuf, seedbytes);
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary(&seedinc, sbuf + seedbytes-i, i) );
i = outbytes;
MBEDTLS_MPI_CHK( mbedtls_md(md_info, sbuf, seedbytes, wbuf+(n-j)*outbytes) );
}
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(&W, wbuf, (n+1)*outbytes) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(&W1, &W, &t2L1) );
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi(&X, &W1, &t2L1) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(&c, &X, &t2q) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int(&p1, &c, 1) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi(&p, &X, &p1) );
if (mbedtls_mpi_cmp_mpi(&p, &t2L1) >= 0) {
/* p >= 2^(L-1) */
if( mbedtls_mpi_is_prime_ext(&p, mr_tests_p, f_rng, p_rng) == 0 ) found_p = 1;
}
}
}
/* FIPS-186-4 A.2.1 Unverifiable Generation of the Generator g
* 1. e = (p - 1)/q
* 2. h = any integer satisfying: 1 < h < (p - 1)
* h could be obtained from a random number generator or from a counter that changes after each use
* 3. g = h^e mod p
* 4. if (g == 1), then go to step 2.
*
*/
/* e = (p - 1)/q */
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int(&p1, &p, 1) );
MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi(&e, &c, &p1, &q) );
i = mbedtls_mpi_size(&p);
do {
/* h is random and 1 < h < (p-1) */
do {
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random(&h, i, f_rng, p_rng) );
} while (mbedtls_mpi_cmp_mpi(&h, &p) >= 0 || mbedtls_mpi_cmp_int(&h, 2) <= 0);
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int(&h1, &h, 1) );
/* g = h^e mod p */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod(&g, &h1, &e, &p, NULL) );
} while (mbedtls_mpi_cmp_int(&g, 1) == 0);
MBEDTLS_MPI_CHK( mbedtls_mpi_copy(&ctx->P, &p) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy(&ctx->Q, &q) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy(&ctx->G, &g) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int(&q1, &q, 1) );
/* private key x should be from range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2) */
do {
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, mbedtls_mpi_size( &q1 ), f_rng, p_rng ) );
} while ( mbedtls_mpi_cmp_int( &ctx->X, 1 ) < 0 || mbedtls_mpi_cmp_mpi( &ctx->X, &q1 ) > 0 );
/* compute y = g^x mod p */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Y, &ctx->G, &ctx->X, &ctx->P, NULL ) );
cleanup:
mbedtls_mpi_free( &t2L1 );
mbedtls_mpi_free( &t2N1 );
mbedtls_mpi_free( &t2seedlen );
mbedtls_mpi_free( &U );
mbedtls_mpi_free( &U1 );
mbedtls_mpi_free( &W );
mbedtls_mpi_free( &W1 );
mbedtls_mpi_free( &X );
mbedtls_mpi_free( &q );
mbedtls_mpi_free( &q1 );
mbedtls_mpi_free( &p );
mbedtls_mpi_free( &p1 );
mbedtls_mpi_free( &e );
mbedtls_mpi_free( &h );
mbedtls_mpi_free( &h1 );
mbedtls_mpi_free( &g );
mbedtls_mpi_free( &c );
mbedtls_mpi_free( &t2q );
mbedtls_mpi_free( &seedinc );
mbedtls_mpi_free( &seedinc1 );
mbedtls_free(sbuf);
cleanup2:
mbedtls_free(wbuf);
cleanup3:
return( ret );
}
/*
* Check group parameters
*/
int mbedtls_dsa_check_pqg( const mbedtls_mpi *P, const mbedtls_mpi *Q, const mbedtls_mpi *G )
{
int ret = 0;
mbedtls_mpi P1, T;
DSA_VALIDATE_RET( P != NULL );
DSA_VALIDATE_RET( Q != NULL );
DSA_VALIDATE_RET( G != NULL );
mbedtls_mpi_init( &P1 );
mbedtls_mpi_init( &T );
if( mbedtls_mpi_cmp_int( P, 0 ) == 0 )
{
ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA;
goto cleanup;
}
if( mbedtls_mpi_cmp_int( Q, 0 ) == 0 )
{
ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA;
goto cleanup;
}
if( mbedtls_mpi_cmp_int( G, 0 ) == 0 )
{
ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA;
goto cleanup;
}
/* Check if P-1 is a multiple of Q */
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, P, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &P1, Q ) );
if( mbedtls_mpi_cmp_int( &T, 0 ) != 0 )
{
ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA;
goto cleanup;
}
/* Check if 1 < G < P */
if( mbedtls_mpi_cmp_int( G, 1 ) <= 0 || mbedtls_mpi_cmp_mpi( G, P ) >= 0 )
{
ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA;
goto cleanup;
}
/* Check if G^Q mod P = 1 */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, G, Q, P, NULL ) );
if( mbedtls_mpi_cmp_int( &T, 1 ) != 0 )
{
ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA;
goto cleanup;
}
cleanup:
mbedtls_mpi_free( &P1 );
mbedtls_mpi_free( &T );
return( ret );
}
/*
* Check public key
*/
int mbedtls_dsa_check_pubkey( const mbedtls_dsa_context *ctx )
{
int ret = 0;
mbedtls_mpi T;
DSA_VALIDATE_RET( ctx != NULL );
/* Y must be in [2, P-1] */
if( mbedtls_mpi_cmp_int( &ctx->Y, 2 ) < 0 ||
mbedtls_mpi_cmp_mpi( &ctx->Y, &ctx->P ) >= 0 )
{
return( MBEDTLS_ERR_DSA_BAD_INPUT_DATA );
}
mbedtls_mpi_init( &T );
/* Y^Q mod P = 1 */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &ctx->Y, &ctx->Q, &ctx->P, NULL ) );
if( mbedtls_mpi_cmp_int( &T, 1 ) != 0 )
{
ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA;
}
cleanup:
mbedtls_mpi_free( &T );
return( ret );
}
/*
* Check private key
*/
int mbedtls_dsa_check_privkey( const mbedtls_dsa_context *ctx )
{
int ret = 0;
mbedtls_mpi T;
DSA_VALIDATE_RET( ctx != NULL );
/* X must be in ]0, Q[ */
if( mbedtls_mpi_cmp_int( &ctx->X, 0 ) <= 0 ||
mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->Q ) >= 0 )
{
return( MBEDTLS_ERR_DSA_BAD_INPUT_DATA );
}
mbedtls_mpi_init( &T );
/* Y = G^X mod P */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &ctx->G, &ctx->X, &ctx->P, NULL ) );
if( mbedtls_mpi_cmp_mpi( &T, &ctx->Y ) != 0 )
{
ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA;
}
cleanup:
mbedtls_mpi_free( &T );
return( ret );
}
/*
* Derive public key from private key
*/
int mbedtls_dsa_pubkey_from_privkey( mbedtls_dsa_context *ctx )
{
int ret = 0;
DSA_VALIDATE_RET( ctx != NULL );
/* X must be in ]0, Q[ */
if( mbedtls_mpi_cmp_int( &ctx->X, 0 ) <= 0 ||
mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->Q ) >= 0 )
{
return( MBEDTLS_ERR_DSA_BAD_INPUT_DATA );
}
/* Y = G^X mod P */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Y, &ctx->G, &ctx->X, &ctx->P, NULL ) );
cleanup:
return( ret );
}
/*
* Convert a signature (given by context) to ASN.1
*/
static int dsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
unsigned char *sig, size_t *slen )
{
int ret;
unsigned char buf[MBEDTLS_DSA_ASN_SIGNATURE_MAX_LEN];
unsigned char *p = buf + sizeof( buf );
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
memcpy( sig, p, len );
*slen = len;
return( 0 );
}
/*
* Compute and write signature
*/
int mbedtls_dsa_sign( mbedtls_dsa_context *ctx,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
mbedtls_mpi k, r, rp, kq, gcd, s, xr, xrh, xrhkq, h;
size_t hashlen, qlen;
DSA_VALIDATE_RET( ctx != NULL );
DSA_VALIDATE_RET( hash != NULL );
DSA_VALIDATE_RET( sig != NULL );
DSA_VALIDATE_RET( slen != NULL );
DSA_VALIDATE_RET( f_rng != NULL );
mbedtls_mpi_init( &k );
mbedtls_mpi_init( &r );
mbedtls_mpi_init( &rp );
mbedtls_mpi_init( &kq );
mbedtls_mpi_init( &gcd );
mbedtls_mpi_init( &s );
mbedtls_mpi_init( &xr );
mbedtls_mpi_init( &xrh );
mbedtls_mpi_init( &xrhkq );
mbedtls_mpi_init( &h );
/* FIPS 186-4 4.7: use leftmost min(bitlen(q), bitlen(hash)) bits of 'hash' */
qlen = mbedtls_mpi_size( &ctx->Q );
hashlen = hlen;
if (hashlen > qlen) hashlen = qlen;
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &h, hash, hashlen ) );
retry:
do
{
/* gen random k */
if( mbedtls_mpi_fill_random( &k, qlen, f_rng, p_rng ) != 0 ) goto cleanup;
/* k should be from range: 1 <= k <= q-1 (see FIPS 186-4 B.2.2) */
if( mbedtls_mpi_cmp_int( &k, 0 ) <= 0 || mbedtls_mpi_cmp_mpi( &k, &ctx->Q ) >= 0 ) goto retry;
/* test gcd */
if( mbedtls_mpi_gcd( &gcd, &k, &ctx->Q ) != 0 ) goto cleanup;
} while( mbedtls_mpi_cmp_int( &gcd, 1 ) != 0 );
/* now find 1/k mod q */
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &kq, &k, &ctx->Q ) );
/* now find r = g^k mod p mod q */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &rp, &ctx->G, &k, &ctx->P, NULL ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &r, &rp, &ctx->Q ) );
/* now find s = (hash + xr)/k mod q */
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &xr, &ctx->X, &r ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &xrh, &xr, &h ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &xrhkq, &xrh, &kq ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &s, &xrhkq, &ctx->Q ) );
MBEDTLS_MPI_CHK( dsa_signature_to_asn1( &r, &s, sig, slen ) );
cleanup:
mbedtls_mpi_free( &k );
mbedtls_mpi_free( &r );
mbedtls_mpi_init( &rp );
mbedtls_mpi_init( &kq );
mbedtls_mpi_init( &gcd );
mbedtls_mpi_free( &s );
mbedtls_mpi_init( &xr );
mbedtls_mpi_init( &xrh );
mbedtls_mpi_init( &xrhkq );
mbedtls_mpi_free( &h );
return( ret );
}
/*
* Read and check signature
*/
int mbedtls_dsa_verify( mbedtls_dsa_context *ctx,
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen )
{
int ret;
unsigned char *p = (unsigned char *) sig;
const unsigned char *end = sig + slen;
size_t len, hashlen, qlen;
mbedtls_mpi r, s, h, w, hw, rw, u1, u2, gu1, yu2, u12, u12p, v, _rr;
DSA_VALIDATE_RET( ctx != NULL );
DSA_VALIDATE_RET( hash != NULL );
DSA_VALIDATE_RET( sig != NULL );
mbedtls_mpi_init( &r );
mbedtls_mpi_init( &s );
mbedtls_mpi_init( &h );
mbedtls_mpi_init( &w );
mbedtls_mpi_init( &hw );
mbedtls_mpi_init( &rw );
mbedtls_mpi_init( &u1 );
mbedtls_mpi_init( &u2 );
mbedtls_mpi_init( &gu1 );
mbedtls_mpi_init( &yu2 );
mbedtls_mpi_init( &u12 );
mbedtls_mpi_init( &u12p );
mbedtls_mpi_init( &v );
mbedtls_mpi_init( &_rr );
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA;
goto cleanup;
}
if( p + len != end )
{
ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA;
goto cleanup;
}
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 ||
( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 )
{
ret = MBEDTLS_ERR_DSA_BAD_INPUT_DATA;
goto cleanup;
}
if( mbedtls_mpi_cmp_int( &r, 0 ) <= 0 || mbedtls_mpi_cmp_mpi( &r, &ctx->Q ) >= 0 ||
mbedtls_mpi_cmp_int( &s, 0 ) <= 0 || mbedtls_mpi_cmp_mpi( &s, &ctx->Q ) >= 0 )
{
ret = MBEDTLS_ERR_DSA_VERIFY_FAILED;
goto cleanup;
}
/* FIPS 186-4 4.7: use leftmost min(bitlen(q), bitlen(hash)) bits of 'hash' */
qlen = mbedtls_mpi_size( &ctx->Q );
hashlen = hlen;
if (hashlen > qlen) hashlen = qlen;
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &h, hash, hashlen ) );
/* w = 1/s mod q */
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &w, &s, &ctx->Q ) );
/* u1 = h*w mod q */
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &hw, &h, &w ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u1, &hw, &ctx->Q ) );
/* u2 = r*w mod q */
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &rw, &r, &w ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u2, &rw, &ctx->Q ) );
/* v = g^u1 * y^u2 mod p mod q */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &gu1, &ctx->G, &u1, &ctx->P, &_rr ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &yu2, &ctx->Y, &u2, &ctx->P, &_rr ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u12, &gu1, &yu2 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u12p, &u12, &ctx->P ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &v, &u12p, &ctx->Q ) );
/* if r = v then it is verified */
if( mbedtls_mpi_cmp_mpi( &v, &r ) != 0 )
{
ret = MBEDTLS_ERR_DSA_VERIFY_FAILED;
goto cleanup;
}
cleanup:
mbedtls_mpi_free( &r );
mbedtls_mpi_free( &s );
mbedtls_mpi_free( &h );
mbedtls_mpi_free( &w );
mbedtls_mpi_free( &u1 );
mbedtls_mpi_free( &u2 );
mbedtls_mpi_init( &gu1 );
mbedtls_mpi_init( &yu2 );
mbedtls_mpi_init( &u12 );
mbedtls_mpi_init( &u12p );
mbedtls_mpi_free( &v );
mbedtls_mpi_free( &_rr );
return( ret );
}
#endif /* MBEDTLS_DSA_ALT */
#if defined(MBEDTLS_SELF_TEST)
static const char *dsa_test_p_hex = "F7E75FDC469067FFDC4E847C51F452DF27303F51D8F2E3E444924563740179E1";
static const char *dsa_test_q_hex = "87E85B349454331564214218435B420E53368DB1";
static const char *dsa_test_g_hex = "F7E75FDC469067FFDC4E847C51F452DF27303F51D8F2E3E444924563740179E1";
static const char *dsa_test_x_hex = "20B4822143298349213489213498213498213948";
static const char *dsa_test_y_hex = "154285095685091850198501985091850918509185091850918509185091850918509185091850918509185091850918509185091850918509185091850918509185";
static const char *dsa_test_hash_hex = "A9993E364706816ABA3E25717850C26C9CD0D89D";
/*
* Checkup routine
*/
int mbedtls_dsa_self_test( int verbose )
{
int ret;
mbedtls_dsa_context dsa;
unsigned char sig[MBEDTLS_DSA_ASN_SIGNATURE_MAX_LEN];
size_t slen;
unsigned char hash[20];
mbedtls_dsa_init( &dsa );
if( verbose != 0 )
mbedtls_printf( " DSA key generation: " );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &dsa.P, 16, dsa_test_p_hex ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &dsa.Q, 16, dsa_test_q_hex ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &dsa.G, 16, dsa_test_g_hex ) );
dsa.len = mbedtls_mpi_size( &dsa.P );
if( ( ret = mbedtls_dsa_genkey( &dsa, NULL, NULL ) ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
if( verbose != 0 )
mbedtls_printf( "passed\n DSA signature: " );
memcpy( hash, dsa_test_hash_hex, 20 );
if( ( ret = mbedtls_dsa_write_signature( &dsa, MBEDTLS_MD_SHA1, hash, 20, sig, &slen, NULL, NULL ) ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
if( verbose != 0 )
mbedtls_printf( "passed\n DSA verification: " );
if( ( ret = mbedtls_dsa_read_signature( &dsa, hash, 20, sig, slen ) ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
if( verbose != 0 )
mbedtls_printf( "passed\n\n" );
exit:
mbedtls_dsa_free( &dsa );
return( ret );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_DSA_C */

View File

@@ -1,6 +1,7 @@
@ cdecl mbedtls_ctr_drbg_free(ptr)
@ cdecl mbedtls_ctr_drbg_init(ptr)
@ cdecl mbedtls_ctr_drbg_random(ptr str long)
@ cdecl mbedtls_ctr_drbg_seed(ptr ptr ptr ptr long)
@ cdecl mbedtls_entropy_free(ptr)
@ cdecl mbedtls_entropy_func(ptr str long)
@ cdecl mbedtls_entropy_init(ptr)
@@ -27,33 +28,92 @@
@ cdecl mbedtls_ssl_config_defaults(ptr long long long)
@ cdecl mbedtls_ssl_conf_dbg(ptr ptr ptr)
@ cdecl mbedtls_ssl_setup(ptr ptr)
@ cdecl mbedtls_cipher_info_from_type(long)
@ cdecl mbedtls_md_info_from_type(long)
@ cdecl mbedtls_pk_get_bitlen(ptr)
@ cdecl mbedtls_ctr_drbg_seed(ptr ptr ptr str long)
@ cdecl mbedtls_md_init(ptr)
@ cdecl mbedtls_md_info_from_type(long)
@ cdecl mbedtls_md_get_size(ptr)
@ cdecl mbedtls_md_setup(ptr ptr long)
@ cdecl mbedtls_md_update(ptr ptr long)
@ cdecl mbedtls_md_hmac_starts(ptr)
@ cdecl mbedtls_md_starts(ptr)
@ cdecl mbedtls_md_finish(ptr ptr)
@ cdecl mbedtls_md_hmac_update(ptr ptr long)
@ cdecl mbedtls_md_hmac_starts(ptr ptr long)
@ cdecl mbedtls_md_hmac_finish(ptr ptr)
@ cdecl mbedtls_md_free(ptr)
@ cdecl mbedtls_md5_init(ptr)
@ cdecl mbedtls_md5_starts(ptr)
@ cdecl mbedtls_md5_update(ptr ptr long)
@ cdecl mbedtls_md5_finish(ptr ptr)
@ cdecl mbedtls_md5_free(ptr)
@ cdecl mbedtls_sha1_init(ptr)
@ cdecl mbedtls_sha1_starts(ptr)
@ cdecl mbedtls_sha1_update(ptr ptr long)
@ cdecl mbedtls_sha1_finish(ptr ptr)
@ cdecl mbedtls_sha1_free(ptr)
@ cdecl mbedtls_sha256_init(ptr)
@ cdecl mbedtls_sha256_starts(ptr long)
@ cdecl mbedtls_sha256_update(ptr ptr long)
@ cdecl mbedtls_sha256_finish(ptr ptr)
@ cdecl mbedtls_sha256_free(ptr)
@ cdecl mbedtls_sha512_init(ptr)
@ cdecl mbedtls_sha512_starts(ptr long)
@ cdecl mbedtls_sha512_update(ptr ptr long)
@ cdecl mbedtls_sha512_finish(ptr ptr)
@ cdecl mbedtls_sha512_free(ptr)
@ cdecl mbedtls_cipher_init(ptr)
@ cdecl mbedtls_cipher_info_from_type(long)
@ cdecl mbedtls_cipher_setup(ptr ptr)
@ cdecl mbedtls_cipher_setkey(ptr ptr long long)
@ cdecl mbedtls_cipher_set_iv(ptr ptr long)
@ cdecl mbedtls_cipher_set_padding_mode(ptr long)
@ cdecl mbedtls_cipher_update(ptr ptr long ptr long)
@ cdecl mbedtls_cipher_update_ad(ptr ptr long)
@ cdecl mbedtls_cipher_check_tag(ptr ptr long)
@ cdecl mbedtls_cipher_write_tag(ptr ptr long)
@ cdecl mbedtls_cipher_finish(ptr ptr long)
@ cdecl mbedtls_cipher_free(ptr)
@ cdecl mbedtls_pk_init(ptr)
@ cdecl mbedtls_pk_get_bitlen(ptr)
@ cdecl mbedtls_pk_get_type(ptr str long)
@ cdecl mbedtls_pk_setup(ptr ptr)
@ cdecl mbedtls_pk_info_from_type(long)
@ cdecl mbedtls_pk_parse_key(ptr ptr long ptr long)
@ cdecl mbedtls_pk_parse_public_key(ptr ptr long)
@ cdecl mbedtls_pk_verify_ext(ptr ptr long ptr long ptr long)
@ cdecl mbedtls_pk_sign(ptr long ptr long ptr ptr ptr ptr)
@ cdecl mbedtls_pk_encrypt(ptr ptr long ptr ptr long ptr ptr)
@ cdecl mbedtls_pk_decrypt(ptr ptr long ptr ptr long ptr ptr)
@ cdecl mbedtls_pk_free(ptr)
@ cdecl mbedtls_ecdh_init(ptr)
@ cdecl mbedtls_ecdh_compute_shared(ptr ptr ptr ptr ptr ptr)
@ cdecl mbedtls_ecdh_free(ptr)
@ cdecl mbedtls_rsa_gen_key(ptr ptr ptr long long)
@ cdecl mbedtls_rsa_import_raw(ptr ptr long ptr long ptr long ptr long ptr long)
@ cdecl mbedtls_rsa_export_raw(ptr ptr long ptr long ptr long ptr long ptr long)
@ cdecl mbedtls_rsa_export_crt(ptr ptr long ptr long ptr long)
@ cdecl mbedtls_rsa_export(ptr ptr ptr ptr ptr ptr)
@ cdecl mbedtls_rsa_set_padding(ptr long long)
@ cdecl mbedtls_rsa_complete(ptr)
@ cdecl mbedtls_rsa_check_pubkey(ptr)
@ cdecl mbedtls_rsa_check_privkey(ptr)
@ cdecl mbedtls_rsa_check_pub_priv(ptr ptr)
@ cdecl mbedtls_ecp_gen_key(long ptr ptr ptr)
@ cdecl mbedtls_ecp_group_load(ptr long)
@ cdecl mbedtls_ecp_point_read_binary(ptr ptr ptr long)
@ cdecl mbedtls_ecp_point_write_binary(ptr ptr ptr long)
@ cdecl mbedtls_ecp_check_pubkey(ptr ptr)
@ cdecl mbedtls_ecp_copy(ptr ptr)
@ cdecl mbedtls_mpi_init(ptr)
@ cdecl mbedtls_mpi_size(ptr)
@ cdecl mbedtls_mpi_lset(ptr long)
@ cdecl mbedtls_mpi_copy(ptr ptr)
@ cdecl mbedtls_mpi_cmp_mpi(ptr ptr)
@ cdecl mbedtls_mpi_cmp_int(ptr long)
@ cdecl mbedtls_mpi_read_binary(ptr ptr long)
@ cdecl mbedtls_mpi_write_binary(ptr ptr long)
@ cdecl mbedtls_mpi_read_string(ptr long str)
@ cdecl mbedtls_mpi_gen_prime(ptr long long ptr ptr)
@ cdecl mbedtls_mpi_sub_int(ptr ptr long)
@ cdecl mbedtls_mpi_div_int(ptr ptr ptr long)
@ cdecl mbedtls_mpi_is_prime_ext(ptr long ptr ptr)
@ cdecl mbedtls_mpi_free(ptr)
@ cdecl mbedtls_asn1_get_len(ptr ptr ptr)
@ cdecl mbedtls_asn1_get_mpi(ptr ptr ptr)
@ cdecl mbedtls_asn1_get_tag(ptr ptr ptr)
@ cdecl mbedtls_asn1_write_len(ptr ptr long)
@ cdecl mbedtls_asn1_write_mpi(ptr ptr ptr)
@ cdecl mbedtls_asn1_write_tag(ptr ptr long)
@ cdecl mbedtls_asn1_write_raw_buffer(ptr ptr ptr long)
@ cdecl mbedtls_dhm_init(ptr)
@ cdecl mbedtls_dhm_make_params(ptr long ptr ptr ptr ptr)
@ cdecl mbedtls_dhm_calc_secret(ptr ptr long ptr ptr ptr)
@ cdecl mbedtls_dhm_free(ptr)
@ cdecl mbedtls_dsa_init(ptr)
@ cdecl mbedtls_dsa_set_group(ptr ptr ptr ptr)
@ cdecl mbedtls_dsa_genkey(ptr long long ptr ptr)
@ cdecl mbedtls_dsa_check_pqg(ptr ptr ptr)
@ cdecl mbedtls_dsa_check_pubkey(ptr)
@ cdecl mbedtls_dsa_check_privkey(ptr)
@ cdecl mbedtls_dsa_pubkey_from_privkey(ptr)
@ cdecl mbedtls_dsa_verify(ptr ptr long ptr long)
@ cdecl mbedtls_dsa_sign(ptr ptr long ptr ptr ptr ptr)
@ cdecl mbedtls_dsa_free(ptr)

View File

@@ -5,11 +5,18 @@ spec2def(bcrypt.dll bcrypt.spec ADD_IMPORTLIB)
list(APPEND SOURCE
bcrypt_main.c
gnutls.c
mbedtls.c
commoncrypto.c
version.rc
${CMAKE_CURRENT_BINARY_DIR}/bcrypt_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/bcrypt.def)
${CMAKE_CURRENT_BINARY_DIR}/bcrypt_stubs.c)
add_library(bcrypt MODULE
${SOURCE}
version.rc
${CMAKE_CURRENT_BINARY_DIR}/bcrypt.def)
add_pch(bcrypt precomp.h SOURCE)
add_library(bcrypt MODULE ${SOURCE})
set_module_type(bcrypt win32dll)
target_link_libraries(bcrypt wine)
add_importlibs(bcrypt mbedtls advapi32 msvcrt kernel32 ntdll)

View File

@@ -1,56 +1,59 @@
@ stub BCryptAddContextFunction
@ stub BCryptAddContextFunctionProvider
@ stdcall BCryptAddContextFunction(long wstr long wstr long)
@ stdcall BCryptAddContextFunctionProvider(long wstr long wstr wstr long)
@ stdcall BCryptCloseAlgorithmProvider(ptr long)
@ stub BCryptConfigureContext
@ stub BCryptConfigureContextFunction
@ stub BCryptCreateContext
@ stdcall BCryptCreateHash(ptr ptr ptr long ptr long long)
@ stub BCryptDecrypt
@ stdcall BCryptDecrypt(ptr ptr long ptr ptr long ptr long ptr long)
@ stub BCryptDeleteContext
@ stub BCryptDeriveKey
@ stdcall BCryptDeriveKey(ptr wstr ptr ptr long ptr long)
@ stdcall BCryptDeriveKeyCapi(ptr ptr ptr long long)
@ stdcall BCryptDeriveKeyPBKDF2(ptr ptr long ptr long int64 ptr long long)
@ stdcall BCryptDestroyHash(ptr)
@ stdcall -stub BCryptDestroyKey(ptr)
@ stub BCryptDestroySecret
@ stub BCryptDuplicateHash
@ stub BCryptDuplicateKey
@ stub BCryptEncrypt
@ stdcall BCryptDestroyKey(ptr)
@ stdcall BCryptDestroySecret(ptr)
@ stdcall BCryptDuplicateHash(ptr ptr ptr long long)
@ stdcall BCryptDuplicateKey(ptr ptr ptr long long)
@ stdcall BCryptEncrypt(ptr ptr long ptr ptr long ptr long ptr long)
@ stdcall BCryptEnumAlgorithms(long ptr ptr long)
@ stub BCryptEnumContextFunctionProviders
@ stub BCryptEnumContextFunctions
@ stdcall BCryptEnumContextFunctions(long wstr long ptr ptr)
@ stub BCryptEnumContexts
@ stub BCryptEnumProviders
@ stub BCryptEnumRegisteredProviders
@ stub BCryptExportKey
@ stub BCryptFinalizeKeyPair
@ stdcall BCryptExportKey(ptr ptr wstr ptr long ptr long)
@ stdcall BCryptFinalizeKeyPair(ptr long)
@ stdcall BCryptFinishHash(ptr ptr long long)
@ stub BCryptFreeBuffer
@ stdcall BCryptFreeBuffer(ptr)
@ stdcall BCryptGenRandom(ptr ptr long long)
@ stub BCryptGenerateKeyPair
@ stub BCryptGenerateSymmetricKey
@ stdcall BCryptGenerateKeyPair(ptr ptr long long)
@ stdcall BCryptGenerateSymmetricKey(ptr ptr ptr long ptr long long)
@ stdcall BCryptGetFipsAlgorithmMode(ptr)
@ stdcall BCryptGetProperty(ptr wstr ptr long ptr long)
@ stdcall BCryptHash(ptr ptr long ptr long ptr long)
@ stdcall BCryptHashData(ptr ptr long long)
@ stub BCryptImportKey
@ stdcall -stub BCryptImportKeyPair(ptr ptr wstr ptr ptr long long)
@ stdcall BCryptImportKey(ptr ptr wstr ptr ptr long ptr long long)
@ stdcall BCryptImportKeyPair(ptr ptr wstr ptr ptr long long)
@ stdcall BCryptKeyDerivation(ptr ptr ptr long ptr long)
@ stdcall BCryptOpenAlgorithmProvider(ptr wstr wstr long)
@ stub BCryptQueryContextConfiguration
@ stub BCryptQueryContextFunctionConfiguration
@ stub BCryptQueryContextFunctionProperty
@ stub BCryptQueryProviderRegistration
@ stub BCryptRegisterConfigChangeNotify
@ stub BCryptRegisterProvider
@ stub BCryptRemoveContextFunction
@ stub BCryptRemoveContextFunctionProvider
@ stdcall BCryptRegisterProvider(wstr long ptr)
@ stdcall BCryptRemoveContextFunction(long wstr long wstr)
@ stdcall BCryptRemoveContextFunctionProvider(long wstr long wstr wstr)
@ stub BCryptResolveProviders
@ stub BCryptSecretAgreement
@ stdcall BCryptSecretAgreement(ptr ptr ptr long)
@ stub BCryptSetAuditingInterface
@ stub BCryptSetContextFunctionProperty
@ stub BCryptSetProperty
@ stub BCryptSignHash
@ stdcall BCryptSetProperty(ptr wstr ptr long long)
@ stdcall BCryptSignHash(ptr ptr ptr long ptr long ptr long)
@ stub BCryptUnregisterConfigChangeNotify
@ stub BCryptUnregisterProvider
@ stdcall -stub BCryptVerifySignature(ptr ptr ptr long ptr long long)
@ stdcall BCryptUnregisterProvider(wstr)
@ stdcall BCryptVerifySignature(ptr ptr ptr long ptr long long)
@ stub GetAsymmetricEncryptionInterface
@ stub GetCipherInterface
@ stub GetHashInterface

View File

@@ -0,0 +1,312 @@
#ifndef __BCRYPT_INTERNAL_H
#define __BCRYPT_INTERNAL_H
#include "precomp.h"
#ifdef SONAME_LIBMBEDTLS
#include <mbedtls/md.h>
#endif
#define MAGIC_DSS1 ('D' | ('S' << 8) | ('S' << 16) | ('1' << 24))
#define MAGIC_DSS2 ('D' | ('S' << 8) | ('S' << 16) | ('2' << 24))
#define MAGIC_ALG (('A' << 24) | ('L' << 16) | ('G' << 8) | '0')
#define MAGIC_HASH (('H' << 24) | ('A' << 16) | ('S' << 8) | 'H')
#define MAGIC_KEY (('K' << 24) | ('E' << 16) | ('Y' << 8) | '0')
#define MAGIC_SECRET (('S' << 24) | ('C' << 16) | ('R' << 8) | 'T')
struct object
{
ULONG magic;
};
enum alg_id
{
/* cipher */
ALG_ID_3DES,
ALG_ID_AES,
ALG_ID_RC4,
/* hash */
ALG_ID_SHA256,
ALG_ID_SHA384,
ALG_ID_SHA512,
ALG_ID_SHA1,
ALG_ID_MD5,
ALG_ID_MD4,
ALG_ID_MD2,
/* asymmetric encryption */
ALG_ID_RSA,
/* secret agreement */
ALG_ID_DH,
ALG_ID_ECDH_P256,
ALG_ID_ECDH_P384,
/* signature */
ALG_ID_RSA_SIGN,
ALG_ID_ECDSA_P256,
ALG_ID_ECDSA_P384,
ALG_ID_DSA,
/* rng */
ALG_ID_RNG,
/* key derivation */
ALG_ID_PBKDF2,
};
enum chain_mode
{
CHAIN_MODE_CBC,
CHAIN_MODE_ECB,
CHAIN_MODE_CFB,
CHAIN_MODE_CCM,
CHAIN_MODE_GCM,
};
struct algorithm
{
struct object hdr;
enum alg_id id;
enum chain_mode mode;
ULONG flags;
};
#define BLOCK_LENGTH_RC4 1
#define BLOCK_LENGTH_3DES 8
#define BLOCK_LENGTH_AES 16
struct key_symmetric
{
enum chain_mode mode;
ULONG block_size;
UCHAR *vector;
ULONG vector_len;
UCHAR *secret;
ULONG secret_len;
CRITICAL_SECTION cs;
};
#define KEY_FLAG_LEGACY_DSA_V2 0x00000001
#define KEY_FLAG_FINALIZED 0x00000002
struct key_asymmetric
{
ULONG bitlen; /* ignored for ECC keys */
ULONG flags;
DSSSEED dss_seed;
};
#define PRIVATE_DATA_SIZE 64
struct key
{
struct object hdr;
enum alg_id alg_id;
UINT64 private[PRIVATE_DATA_SIZE]; /* private data for backend */
union
{
struct key_symmetric s;
struct key_asymmetric a;
} u;
};
struct secret
{
struct object hdr;
struct key *privkey;
struct key *pubkey;
};
struct key_symmetric_set_auth_data_params
{
struct key *key;
UCHAR *auth_data;
ULONG len;
#ifdef SONAME_LIBMBEDTLS
BOOL encrypt;
#endif
};
struct key_symmetric_encrypt_params
{
struct key *key;
const UCHAR *input;
unsigned input_len;
UCHAR *output;
ULONG output_len;
};
struct key_symmetric_decrypt_params
{
struct key *key;
const UCHAR *input;
unsigned input_len;
UCHAR *output;
ULONG output_len;
};
struct key_symmetric_get_tag_params
{
struct key *key;
UCHAR *tag;
ULONG len;
};
struct key_asymmetric_decrypt_params
{
struct key *key;
UCHAR *input;
ULONG input_len;
void *padding;
UCHAR *output;
ULONG output_len;
ULONG *ret_len;
ULONG flags;
};
struct key_asymmetric_encrypt_params
{
struct key *key;
UCHAR *input;
ULONG input_len;
void *padding;
UCHAR *output;
ULONG output_len;
ULONG *ret_len;
ULONG flags;
};
struct key_asymmetric_duplicate_params
{
struct key *key_orig;
struct key *key_copy;
};
struct key_asymmetric_sign_params
{
struct key *key;
void *padding;
UCHAR *input;
ULONG input_len;
UCHAR *output;
ULONG output_len;
ULONG *ret_len;
ULONG flags;
};
struct key_asymmetric_verify_params
{
struct key *key;
void *padding;
UCHAR *hash;
ULONG hash_len;
UCHAR *signature;
ULONG signature_len;
ULONG flags;
};
#define KEY_EXPORT_FLAG_PUBLIC 0x00000001
#define KEY_EXPORT_FLAG_RSA_FULL 0x00000002
#define KEY_EXPORT_FLAG_DH_PARAMETERS 0x00000004
struct key_asymmetric_export_params
{
struct key *key;
ULONG flags;
UCHAR *buf;
ULONG len;
ULONG *ret_len;
};
#define KEY_IMPORT_FLAG_PUBLIC 0x00000001
#define KEY_IMPORT_FLAG_DH_PARAMETERS 0x00000002
struct key_asymmetric_import_params
{
struct key *key;
ULONG flags;
UCHAR *buf;
ULONG len;
};
struct key_asymmetric_derive_key_params
{
struct key *privkey;
struct key *pubkey;
UCHAR *output;
ULONG output_len;
ULONG *ret_len;
};
#define HASH_FLAG_HMAC 0x01
#define HASH_FLAG_REUSABLE 0x02
#if defined(HAVE_GNUTLS_HASH)
struct hash
{
struct object hdr;
enum alg_id alg_id;
ULONG flags;
UCHAR *secret;
ULONG secret_len;
union
{
gnutls_hash_hd_t hash_handle;
gnutls_hmac_hd_t hmac_handle;
} u;
};
#elif defined(SONAME_LIBMBEDTLS)
struct hash
{
struct object hdr;
enum alg_id alg_id;
ULONG flags;
UCHAR *secret;
ULONG secret_len;
mbedtls_md_context_t hash_ctx;
};
#else
struct hash
{
struct object hdr;
enum alg_id alg_id;
ULONG flags;
UCHAR *secret;
ULONG secret_len;
};
#endif
extern NTSTATUS hash_init( struct hash *hash );
extern NTSTATUS hmac_init( struct hash *hash, UCHAR *key, ULONG key_size );
extern NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size );
extern NTSTATUS hmac_update( struct hash *hash, UCHAR *input, ULONG size );
extern NTSTATUS hash_finish( struct hash *hash, UCHAR *output );
extern NTSTATUS hmac_finish( struct hash *hash, UCHAR *output );
extern NTSTATUS hash_get_size( struct hash *hash, ULONG *output );
extern NTSTATUS process_detach( void *args );
extern NTSTATUS process_attach( void *args );
extern NTSTATUS key_symmetric_set_auth_data( void *args );
extern NTSTATUS key_symmetric_vector_reset( void *args );
extern NTSTATUS key_symmetric_encrypt_internal( void *args );
extern NTSTATUS key_symmetric_decrypt_internal( void *args );
extern NTSTATUS key_symmetric_get_tag( void *args );
extern NTSTATUS key_symmetric_destroy( void *args );
extern NTSTATUS key_asymmetric_generate( void *args );
extern NTSTATUS key_asymmetric_export( void *args );
extern NTSTATUS key_asymmetric_import( void *args );
extern NTSTATUS key_asymmetric_verify( void *args );
extern NTSTATUS key_asymmetric_sign( void *args );
extern NTSTATUS key_asymmetric_destroy( void *args );
extern NTSTATUS key_asymmetric_duplicate( void *args );
extern NTSTATUS key_asymmetric_decrypt( void *args );
extern NTSTATUS key_asymmetric_encrypt( void *args );
extern NTSTATUS key_asymmetric_derive_key( void *args );
#ifndef ARRAY_SIZE
#define ARRAY_SIZE ARRAYSIZE
#endif
#endif /* __BCRYPT_INTERNAL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,235 @@
#include "precomp.h"
#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
NTSTATUS process_attach( void *args )
{
return STATUS_SUCCESS;
}
NTSTATUS process_detach( void *args )
{
return STATUS_SUCCESS;
}
NTSTATUS hash_init( struct hash *hash )
{
switch (hash->alg_id)
{
case ALG_ID_MD5:
CC_MD5_Init( &hash->u.md5_ctx );
break;
case ALG_ID_SHA1:
CC_SHA1_Init( &hash->u.sha1_ctx );
break;
case ALG_ID_SHA256:
CC_SHA256_Init( &hash->u.sha256_ctx );
break;
case ALG_ID_SHA384:
CC_SHA384_Init( &hash->u.sha512_ctx );
break;
case ALG_ID_SHA512:
CC_SHA512_Init( &hash->u.sha512_ctx );
break;
default:
ERR( "unhandled id %u\n", hash->alg_id );
return STATUS_NOT_IMPLEMENTED;
}
return STATUS_SUCCESS;
}
NTSTATUS hmac_init( struct hash *hash, UCHAR *key, ULONG key_size )
{
CCHmacAlgorithm cc_algorithm;
switch (hash->alg_id)
{
case ALG_ID_MD5:
cc_algorithm = kCCHmacAlgMD5;
break;
case ALG_ID_SHA1:
cc_algorithm = kCCHmacAlgSHA1;
break;
case ALG_ID_SHA256:
cc_algorithm = kCCHmacAlgSHA256;
break;
case ALG_ID_SHA384:
cc_algorithm = kCCHmacAlgSHA384;
break;
case ALG_ID_SHA512:
cc_algorithm = kCCHmacAlgSHA512;
break;
default:
ERR( "unhandled id %u\n", hash->alg_id );
return STATUS_NOT_IMPLEMENTED;
}
CCHmacInit( &hash->u.hmac_ctx, cc_algorithm, key, key_size );
return STATUS_SUCCESS;
}
NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size )
{
switch (hash->alg_id)
{
case ALG_ID_MD5:
CC_MD5_Update( &hash->u.md5_ctx, input, size );
break;
case ALG_ID_SHA1:
CC_SHA1_Update( &hash->u.sha1_ctx, input, size );
break;
case ALG_ID_SHA256:
CC_SHA256_Update( &hash->u.sha256_ctx, input, size );
break;
case ALG_ID_SHA384:
CC_SHA384_Update( &hash->u.sha512_ctx, input, size );
break;
case ALG_ID_SHA512:
CC_SHA512_Update( &hash->u.sha512_ctx, input, size );
break;
default:
ERR( "unhandled id %u\n", hash->alg_id );
return STATUS_NOT_IMPLEMENTED;
}
return STATUS_SUCCESS;
}
NTSTATUS hmac_update( struct hash *hash, UCHAR *input, ULONG size )
{
CCHmacUpdate( &hash->u.hmac_ctx, input, size );
return STATUS_SUCCESS;
}
NTSTATUS hash_finish( struct hash *hash, UCHAR *output )
{
switch (hash->alg_id)
{
case ALG_ID_MD5:
CC_MD5_Final( output, &hash->u.md5_ctx );
break;
case ALG_ID_SHA1:
CC_SHA1_Final( output, &hash->u.sha1_ctx );
break;
case ALG_ID_SHA256:
CC_SHA256_Final( output, &hash->u.sha256_ctx );
break;
case ALG_ID_SHA384:
CC_SHA384_Final( output, &hash->u.sha512_ctx );
break;
case ALG_ID_SHA512:
CC_SHA512_Final( output, &hash->u.sha512_ctx );
break;
default:
ERR( "unhandled id %u\n", hash->alg_id );
break;
}
return STATUS_SUCCESS;
}
NTSTATUS hmac_finish( struct hash *hash, UCHAR *output )
{
CCHmacFinal( &hash->u.hmac_ctx, output );
return STATUS_SUCCESS;
}
NTSTATUS key_symmetric_set_auth_data( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_symmetric_vector_reset( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_symmetric_encrypt_internal( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_symmetric_decrypt_internal( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_symmetric_get_tag( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_symmetric_destroy( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_asymmetric_generate( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_asymmetric_export( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_asymmetric_import( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_asymmetric_verify( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_asymmetric_sign( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_asymmetric_destroy( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_asymmetric_duplicate( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_asymmetric_decrypt( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_asymmetric_encrypt( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS key_asymmetric_derive_key( void *args )
{
return STATUS_NOT_IMPLEMENTED;
}
#endif /* HAVE_COMMONCRYPTO_COMMONDIGEST_H */

2901
dll/win32/bcrypt/gnutls.c Normal file

File diff suppressed because it is too large Load Diff

2804
dll/win32/bcrypt/mbedtls.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
#ifndef _BCRYPT_PRECOMP_H
#define _BCRYPT_PRECOMP_H
#include <wine/config.h>
#include <wine/port.h>
#include <ntstatus.h>
#define WIN32_NO_STATUS
#include <windef.h>
#include <winbase.h>
#include <ntsecapi.h>
#include <wincrypt.h>
#include <bcrypt.h>
#include <wine/debug.h>
#include <wine/unicode.h>
#include <wine/library.h>
#include "bcrypt_internal.h"
#endif /* !_BCRYPT_PRECOMP_H */

View File

@@ -58,7 +58,7 @@ dll/win32/atl80 # Synced to Wine-10.0
dll/win32/atl100 # Synced to Wine-10.0
dll/win32/avifil32 # Synced to Wine-10.0
dll/win32/avrt # Synced to Wine-10.0
dll/win32/bcrypt # Synced to WineStaging-1.9.23 (+ winetest synced to 8d8936cbb6fea3cac862e059e814527f5361f48b, a.k.a 20161206-BJ)
dll/win32/bcrypt # Synced to WineStaging-10.6 (+ winetest synced to d9148e48a3257ae80361f02f0bb7a2d607ef18ec)
dll/win32/bcryptprimitives # Synced to Wine-10.0
dll/win32/bluetoothapis # Synced to Wine-10.0
dll/win32/cabinet # Synced to Wine-10.0

File diff suppressed because it is too large Load Diff

View File

@@ -40,7 +40,6 @@ typedef _Return_type_success_(return >= 0) LONG NTSTATUS;
typedef NTSTATUS *PNTSTATUS;
#endif
#if defined(_MSC_VER) || defined(__MINGW32__)
#define BCRYPT_ALGORITHM_NAME L"AlgorithmName"
#define BCRYPT_AUTH_TAG_LENGTH L"AuthTagLength"
#define BCRYPT_BLOCK_LENGTH L"BlockLength"
@@ -106,6 +105,7 @@ typedef NTSTATUS *PNTSTATUS;
#define BCRYPT_SHA256_ALGORITHM L"SHA256"
#define BCRYPT_SHA384_ALGORITHM L"SHA384"
#define BCRYPT_SHA512_ALGORITHM L"SHA512"
#define BCRYPT_PBKDF2_ALGORITHM L"PBKDF2"
#define BCRYPT_CHAIN_MODE_NA L"ChainingModeN/A"
#define BCRYPT_CHAIN_MODE_CBC L"ChainingModeCBC"
@@ -121,90 +121,6 @@ typedef NTSTATUS *PNTSTATUS;
#define BCRYPT_KDF_RAW_SECRET L"TRUNCATE"
#define BCRYPT_DH_PARAMETERS L"DHParameters"
#else
static const WCHAR BCRYPT_ALGORITHM_NAME[] = {'A','l','g','o','r','i','t','h','m','N','a','m','e',0};
static const WCHAR BCRYPT_AUTH_TAG_LENGTH[] = {'A','u','t','h','T','a','g','L','e','n','g','t','h',0};
static const WCHAR BCRYPT_BLOCK_LENGTH[] = {'B','l','o','c','k','L','e','n','g','t','h',0};
static const WCHAR BCRYPT_BLOCK_SIZE_LIST[] = {'B','l','o','c','k','S','i','z','e','L','i','s','t',0};
static const WCHAR BCRYPT_CHAINING_MODE[] = {'C','h','a','i','n','i','n','g','M','o','d','e',0};
static const WCHAR BCRYPT_EFFECTIVE_KEY_LENGTH[] = {'E','f','f','e','c','t','i','v','e','K','e','y','L','e','n','g','t','h',0};
static const WCHAR BCRYPT_HASH_BLOCK_LENGTH[] = {'H','a','s','h','B','l','o','c','k','L','e','n','g','t','h',0};
static const WCHAR BCRYPT_HASH_LENGTH[] = {'H','a','s','h','D','i','g','e','s','t','L','e','n','g','t','h',0};
static const WCHAR BCRYPT_HASH_OID_LIST[] = {'H','a','s','h','O','I','D','L','i','s','t',0};
static const WCHAR BCRYPT_KEY_LENGTH[] = {'K','e','y','L','e','n','g','t','h',0};
static const WCHAR BCRYPT_KEY_LENGTHS[] = {'K','e','y','L','e','n','g','t','h','s',0};
static const WCHAR BCRYPT_KEY_OBJECT_LENGTH[] = {'K','e','y','O','b','j','e','c','t','L','e','n','g','t','h',0};
static const WCHAR BCRYPT_KEY_STRENGTH[] = {'K','e','y','S','t','r','e','n','g','t','h',0};
static const WCHAR BCRYPT_OBJECT_LENGTH[] = {'O','b','j','e','c','t','L','e','n','g','t','h',0};
static const WCHAR BCRYPT_PADDING_SCHEMES[] = {'P','a','d','d','i','n','g','S','c','h','e','m','e','s',0};
static const WCHAR BCRYPT_PROVIDER_HANDLE[] = {'P','r','o','v','i','d','e','r','H','a','n','d','l','e',0};
static const WCHAR BCRYPT_SIGNATURE_LENGTH[] = {'S','i','g','n','a','t','u','r','e','L','e','n','g','t','h',0};
static const WCHAR BCRYPT_PUBLIC_KEY_LENGTH[] = {'P','u','b','l','i','c','K','e','y','L','e','n','g','t','h',0};
static const WCHAR BCRYPT_OPAQUE_KEY_BLOB[] = {'O','p','a','q','u','e','K','e','y','B','l','o','b',0};
static const WCHAR BCRYPT_KEY_DATA_BLOB[] = {'K','e','y','D','a','t','a','B','l','o','b',0};
static const WCHAR BCRYPT_AES_WRAP_KEY_BLOB[] = {'R','f','c','3','5','6','5','K','e','y','W','r','a','p','B','l','o','b',0};
static const WCHAR BCRYPT_ECCPUBLIC_BLOB[] = {'E','C','C','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR BCRYPT_ECCPRIVATE_BLOB[] = {'E','C','C','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_RSAPUBLIC_BLOB[] = {'R','S','A','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR BCRYPT_RSAPRIVATE_BLOB[] = {'R','S','A','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_RSAFULLPRIVATE_BLOB[] = {'R','S','A','F','U','L','L','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_DSA_PUBLIC_BLOB[] = {'D','S','A','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR BCRYPT_DSA_PRIVATE_BLOB[] = {'D','S','A','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_PUBLIC_KEY_BLOB[] = {'P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR BCRYPT_PRIVATE_KEY_BLOB[] = {'P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR BCRYPT_DH_PUBLIC_BLOB[] = {'D','H','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR BCRYPT_DH_PRIVATE_BLOB[] = {'D','H','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR LEGACY_DSA_PUBLIC_BLOB[] = {'C','A','P','I','D','S','A','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR LEGACY_DSA_PRIVATE_BLOB[] = {'C','A','P','I','D','S','A','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR LEGACY_DSA_V2_PUBLIC_BLOB[] = {'V','2','C','A','P','I','D','S','A','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR LEGACY_DSA_V2_PRIVATE_BLOB[] = {'V','2','C','A','P','I','D','S','A','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR LEGACY_RSAPUBLIC_BLOB[] = {'C','A','P','I','P','U','B','L','I','C','B','L','O','B',0};
static const WCHAR LEGACY_RSAPRIVATE_BLOB[] = {'C','A','P','I','P','R','I','V','A','T','E','B','L','O','B',0};
static const WCHAR MS_PRIMITIVE_PROVIDER[] = \
{'M','i','c','r','o','s','o','f','t',' ','P','r','i','m','i','t','i','v','e',' ','P','r','o','v','i','d','e','r',0};
static const WCHAR MS_PLATFORM_CRYPTO_PROVIDER[] = \
{'M','i','c','r','o','s','o','f','t',' ','P','l','a','t','f','o','r','m',' ','C','r','y','p','t','o',' ','P','r','o','v','i','d','e','r',0};
static const WCHAR BCRYPT_3DES_ALGORITHM[] = {'3','D','E','S',0};
static const WCHAR BCRYPT_AES_ALGORITHM[] = {'A','E','S',0};
static const WCHAR BCRYPT_DES_ALGORITHM[] = {'D','E','S',0};
static const WCHAR BCRYPT_DH_ALGORITHM[] = {'D','H',0};
static const WCHAR BCRYPT_DSA_ALGORITHM[] = {'D','S','A',0};
static const WCHAR BCRYPT_ECDH_P256_ALGORITHM[] = {'E','C','D','H','_','P','2','5','6',0};
static const WCHAR BCRYPT_ECDH_P384_ALGORITHM[] = {'E','C','D','H','_','P','3','8','4',0};
static const WCHAR BCRYPT_ECDSA_P256_ALGORITHM[] = {'E','C','D','S','A','_','P','2','5','6',0};
static const WCHAR BCRYPT_ECDSA_P384_ALGORITHM[] = {'E','C','D','S','A','_','P','3','8','4',0};
static const WCHAR BCRYPT_ECDSA_P521_ALGORITHM[] = {'E','C','D','S','A','_','P','5','2','1',0};
static const WCHAR BCRYPT_MD2_ALGORITHM[] = {'M','D','2',0};
static const WCHAR BCRYPT_MD4_ALGORITHM[] = {'M','D','4',0};
static const WCHAR BCRYPT_MD5_ALGORITHM[] = {'M','D','5',0};
static const WCHAR BCRYPT_RC2_ALGORITHM[] = {'R','C','2',0};
static const WCHAR BCRYPT_RC4_ALGORITHM[] = {'R','C','4',0};
static const WCHAR BCRYPT_RNG_ALGORITHM[] = {'R','N','G',0};
static const WCHAR BCRYPT_RSA_ALGORITHM[] = {'R','S','A',0};
static const WCHAR BCRYPT_RSA_SIGN_ALGORITHM[] = {'R','S','A','_','S','I','G','N',0};
static const WCHAR BCRYPT_SHA1_ALGORITHM[] = {'S','H','A','1',0};
static const WCHAR BCRYPT_SHA256_ALGORITHM[] = {'S','H','A','2','5','6',0};
static const WCHAR BCRYPT_SHA384_ALGORITHM[] = {'S','H','A','3','8','4',0};
static const WCHAR BCRYPT_SHA512_ALGORITHM[] = {'S','H','A','5','1','2',0};
static const WCHAR BCRYPT_CHAIN_MODE_NA[] = {'C','h','a','i','n','i','n','g','M','o','d','e','N','/','A',0};
static const WCHAR BCRYPT_CHAIN_MODE_CBC[] = {'C','h','a','i','n','i','n','g','M','o','d','e','C','B','C',0};
static const WCHAR BCRYPT_CHAIN_MODE_ECB[] = {'C','h','a','i','n','i','n','g','M','o','d','e','E','C','B',0};
static const WCHAR BCRYPT_CHAIN_MODE_CFB[] = {'C','h','a','i','n','i','n','g','M','o','d','e','C','F','B',0};
static const WCHAR BCRYPT_CHAIN_MODE_CCM[] = {'C','h','a','i','n','i','n','g','M','o','d','e','C','C','M',0};
static const WCHAR BCRYPT_CHAIN_MODE_GCM[] = {'C','h','a','i','n','i','n','g','M','o','d','e','G','C','M',0};
static const WCHAR BCRYPT_KDF_HASH[] = {'H','A','S','H',0};
static const WCHAR BCRYPT_KDF_HMAC[] = {'H','M','A','C',0};
static const WCHAR BCRYPT_KDF_TLS_PRF[] = {'T','L','S','_','P','R','F',0};
static const WCHAR BCRYPT_KDF_SP80056A_CONCAT[] = {'S','P','8','0','0','_','5','6','A','_','C','O','N','C','A','T',0};
static const WCHAR BCRYPT_KDF_RAW_SECRET[] = {'T','R','U','N','C','A','T','E',0};
static const WCHAR BCRYPT_DH_PARAMETERS[] = {'D','H','P','a','r','a','m','e','t','e','r','s',0};
#endif
#define BCRYPT_ECDSA_PUBLIC_P256_MAGIC 0x31534345
#define BCRYPT_ECDSA_PRIVATE_P256_MAGIC 0x32534345
@@ -226,6 +142,7 @@ static const WCHAR BCRYPT_DH_PARAMETERS[] = {'D','H','P','a','r','a','m','e','t'
#define BCRYPT_SECRET_AGREEMENT_OPERATION 0x00000008
#define BCRYPT_SIGNATURE_OPERATION 0x00000010
#define BCRYPT_RNG_OPERATION 0x00000020
#define BCRYPT_KEY_DERIVATION_OPERATION 0x00000040
#define BCRYPT_CIPHER_INTERFACE 0x00000001
#define BCRYPT_HASH_INTERFACE 0x00000002
@@ -413,9 +330,23 @@ typedef struct _BCRYPT_KEY_DATA_BLOB_HEADER
ULONG cbKeyData;
} BCRYPT_KEY_DATA_BLOB_HEADER, *PBCRYPT_KEY_DATA_BLOB_HEADER;
#define KDF_HASH_ALGORITHM 0x00000000
#define KDF_SECRET_PREPEND 0x00000001
#define KDF_SECRET_APPEND 0x00000002
#define KDF_HASH_ALGORITHM 0x00
#define KDF_SECRET_PREPEND 0x01
#define KDF_SECRET_APPEND 0x02
#define KDF_HMAC_KEY 0x03
#define KDF_TLS_PRF_LABEL 0x04
#define KDF_TLS_PRF_SEED 0x05
#define KDF_SECRET_HANDLE 0x06
#define KDF_TLS_PRF_PROTOCOL 0x07
#define KDF_ALGORITHMID 0x08
#define KDF_PARTYUINFO 0x09
#define KDF_PARTYVINFO 0x0a
#define KDF_SUPPPUBINFO 0x0b
#define KDF_SUPPPRIVINFO 0x0c
#define KDF_LABEL 0x0d
#define KDF_CONTEXT 0x0e
#define KDF_SALT 0x0f
#define KDF_ITERATION_COUNT 0x10
typedef struct _BCryptBuffer
{
@@ -552,6 +483,7 @@ NTSTATUS WINAPI BCryptHash(BCRYPT_ALG_HANDLE, PUCHAR, ULONG, PUCHAR, ULONG, PUCH
NTSTATUS WINAPI BCryptHashData(BCRYPT_HASH_HANDLE, PUCHAR, ULONG, ULONG);
NTSTATUS WINAPI BCryptImportKey(BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE, LPCWSTR, BCRYPT_KEY_HANDLE *, PUCHAR, ULONG, PUCHAR, ULONG, ULONG);
NTSTATUS WINAPI BCryptImportKeyPair(BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE, LPCWSTR, BCRYPT_KEY_HANDLE *, UCHAR *, ULONG, ULONG);
NTSTATUS WINAPI BCryptKeyDerivation(BCRYPT_KEY_HANDLE, BCryptBufferDesc *, UCHAR *, ULONG, ULONG *, ULONG);
NTSTATUS WINAPI BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *, LPCWSTR, LPCWSTR, ULONG);
NTSTATUS WINAPI BCryptRemoveContextFunction(ULONG, LPCWSTR, ULONG, LPCWSTR);
NTSTATUS WINAPI BCryptSecretAgreement(BCRYPT_KEY_HANDLE, BCRYPT_KEY_HANDLE, BCRYPT_SECRET_HANDLE *, ULONG);

View File

@@ -135,6 +135,11 @@ typedef enum {
MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */
MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */
MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */
#ifdef __REACTOS__
MBEDTLS_CIPHER_AES_128_CFB8, /**< AES cipher with 128-bit CFB8 mode. */
MBEDTLS_CIPHER_AES_192_CFB8, /**< AES cipher with 192-bit CFB8 mode. */
MBEDTLS_CIPHER_AES_256_CFB8, /**< AES cipher with 256-bit CFB8 mode. */
#endif
MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */
MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */
MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */

View File

@@ -2366,6 +2366,21 @@
*/
#define MBEDTLS_ECDSA_C
/**
* \def MBEDTLS_DSA_C
*
* Enable the DSA library.
*
* Module: library/dsa.c
* Caller:
*
* This module is used by the following key exchanges:
* DSA
*
* Requires: MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C
*/
#define MBEDTLS_DSA_C
/**
* \def MBEDTLS_ECJPAKE_C
*
@@ -2531,7 +2546,7 @@
* it, and considering stronger message digests instead.
*
*/
//#define MBEDTLS_MD2_C
#define MBEDTLS_MD2_C
/**
* \def MBEDTLS_MD4_C
@@ -2548,7 +2563,7 @@
* it, and considering stronger message digests instead.
*
*/
//#define MBEDTLS_MD4_C
#define MBEDTLS_MD4_C
/**
* \def MBEDTLS_MD5_C

View File

@@ -0,0 +1,183 @@
/*
* Digital Signature Algorithm (DSA)
*
* Copyright The Mbed TLS Contributors
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
*/
#ifndef MBEDTLS_DSA_H
#define MBEDTLS_DSA_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "bignum.h"
#include "md.h"
/*
* DSA-specific error codes
*/
#define MBEDTLS_ERR_DSA_BAD_INPUT_DATA -0x3180 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_DSA_INVALID_KEY -0x3200 /**< The private key is not valid. */
#define MBEDTLS_ERR_DSA_VERIFY_FAILED -0x3280 /**< The signature is not valid. */
#define MBEDTLS_ERR_DSA_ALLOC_FAILED -0x3300 /**< Memory allocation failed. */
#define MBEDTLS_ERR_DSA_RANDOM_FAILED -0x3380 /**< Generation of random value, such as k, failed. */
#define MBEDTLS_ERR_DSA_FILE_IO_ERROR -0x3400 /**< Read/write of file failed. */
#define MBEDTLS_ERR_DSA_SIG_LEN_MISMATCH -0x3480 /**< The signature is valid but its length is not matches to the given length. */
#define MBEDTLS_DSA_ASN_SIGNATURE_MAX_LEN 64
/* Max DSA group size in bytes */
#define MBEDTLS_DSA_MAX_GROUP 64
/* Max DSA modulus size in bytes (the actual DSA size, max 8192 bits) */
#define MBEDTLS_DSA_MAX_MODULUS 1024
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief DSA context structure
*/
typedef struct mbedtls_dsa_context
{
size_t len;
mbedtls_mpi P; /*!< prime modulus P */
mbedtls_mpi Q; /*!< prime sub-modulus Q */
mbedtls_mpi G; /*!< generator G */
mbedtls_mpi Y; /*!< public key Y = G^X mod P */
mbedtls_mpi X; /*!< private key X */
}
mbedtls_dsa_context;
/**
* \brief This function initializes a DSA context.
*
* \param ctx The DSA context to initialize.
*/
void mbedtls_dsa_init( mbedtls_dsa_context *ctx );
/**
* \brief This function frees a DSA context.
*
* \param ctx The DSA context to free.
*/
void mbedtls_dsa_free( mbedtls_dsa_context *ctx );
/**
* \brief This function sets the DSA group parameters.
*
* \param ctx The DSA context to store the parameters in.
* \param P The prime modulus P.
* \param Q The prime sub-modulus Q.
* \param G The generator G.
*
* \return 0 if successful, or a specific error code.
*/
int mbedtls_dsa_set_group( mbedtls_dsa_context *ctx, const mbedtls_mpi *P, const mbedtls_mpi *Q, const mbedtls_mpi *G );
/**
* \brief This function generates a DSA keypair.
*
* \param ctx The DSA context to store the keypair in.
* \param group_size The group size for the keypair.
* \param modulus_size The modulus size for the keypair.
* \param f_rng The RNG function.
* \param p_rng The RNG context.
*
* \return 0 if successful, or a specific error code.
*/
int mbedtls_dsa_genkey( mbedtls_dsa_context *ctx, size_t group_size, size_t modulus_size,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
/**
* \brief This function checks if the DSA group parameters are valid.
*
* \param P The prime modulus P.
* \param Q The prime sub-modulus Q.
* \param G The generator G.
*
* \return 0 if successful, or a specific error code.
*/
int mbedtls_dsa_check_pqg( const mbedtls_mpi *P, const mbedtls_mpi *Q, const mbedtls_mpi *G );
/**
* \brief This function checks if the public key is valid.
*
* \param ctx The DSA context.
*
* \return 0 if successful, or a specific error code.
*/
int mbedtls_dsa_check_pubkey( const mbedtls_dsa_context *ctx );
/**
* \brief This function checks if the private key is valid.
*
* \param ctx The DSA context.
*
* \return 0 if successful, or a specific error code.
*/
int mbedtls_dsa_check_privkey( const mbedtls_dsa_context *ctx );
/**
* \brief This function derived public key from private key.
*
* \param ctx The DSA context.
*
* \return 0 if successful, or a specific error code.
*/
int mbedtls_dsa_pubkey_from_privkey( mbedtls_dsa_context *ctx );
/**
* \brief This function computes the DSA signature of a message hash.
*
* \param ctx The DSA context.
* \param hash The message hash.
* \param hlen The length of the hash.
* \param sig The buffer to write the signature to.
* \param slen The length of the signature written.
* \param f_rng The RNG function.
* \param p_rng The RNG context.
*
* \return 0 if successful, or a specific error code.
*/
int mbedtls_dsa_sign( mbedtls_dsa_context *ctx,
const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief This function reads and verifies a DSA signature.
*
* \param ctx The DSA context.
* \param hash The message hash.
* \param hlen The length of the hash.
* \param sig The signature to read and verify.
* \param slen The length of the signature.
*
* \return 0 if successful, or a specific error code.
*/
int mbedtls_dsa_verify( mbedtls_dsa_context *ctx,
const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief The DSA checkup routine.
*
* \param verbose Verbosity level.
*
* \return 0 if successful, or 1 if the test failed.
*/
int mbedtls_dsa_self_test( int verbose );
#endif
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_DSA_H */