Blame crypto/fips/fips_ecdh_selftest.c

Packit c4476c
/* fips/ecdh/fips_ecdh_selftest.c */
Packit c4476c
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
Packit c4476c
 * project 2011.
Packit c4476c
 */
Packit c4476c
/* ====================================================================
Packit c4476c
 * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
Packit c4476c
 *
Packit c4476c
 * Redistribution and use in source and binary forms, with or without
Packit c4476c
 * modification, are permitted provided that the following conditions
Packit c4476c
 * are met:
Packit c4476c
 *
Packit c4476c
 * 1. Redistributions of source code must retain the above copyright
Packit c4476c
 *    notice, this list of conditions and the following disclaimer. 
Packit c4476c
 *
Packit c4476c
 * 2. Redistributions in binary form must reproduce the above copyright
Packit c4476c
 *    notice, this list of conditions and the following disclaimer in
Packit c4476c
 *    the documentation and/or other materials provided with the
Packit c4476c
 *    distribution.
Packit c4476c
 *
Packit c4476c
 * 3. All advertising materials mentioning features or use of this
Packit c4476c
 *    software must display the following acknowledgment:
Packit c4476c
 *    "This product includes software developed by the OpenSSL Project
Packit c4476c
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
Packit c4476c
 *
Packit c4476c
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
Packit c4476c
 *    endorse or promote products derived from this software without
Packit c4476c
 *    prior written permission. For written permission, please contact
Packit c4476c
 *    licensing@OpenSSL.org.
Packit c4476c
 *
Packit c4476c
 * 5. Products derived from this software may not be called "OpenSSL"
Packit c4476c
 *    nor may "OpenSSL" appear in their names without prior written
Packit c4476c
 *    permission of the OpenSSL Project.
Packit c4476c
 *
Packit c4476c
 * 6. Redistributions of any form whatsoever must retain the following
Packit c4476c
 *    acknowledgment:
Packit c4476c
 *    "This product includes software developed by the OpenSSL Project
Packit c4476c
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
Packit c4476c
 *
Packit c4476c
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
Packit c4476c
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit c4476c
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
Packit c4476c
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
Packit c4476c
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit c4476c
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
Packit c4476c
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Packit c4476c
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit c4476c
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
Packit c4476c
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Packit c4476c
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
Packit c4476c
 * OF THE POSSIBILITY OF SUCH DAMAGE.
Packit c4476c
 * ====================================================================
Packit c4476c
 *
Packit c4476c
 */
Packit c4476c
Packit c4476c
#define OPENSSL_FIPSAPI
Packit c4476c
Packit c4476c
#include <string.h>
Packit c4476c
#include <openssl/crypto.h>
Packit c4476c
#include <openssl/ec.h>
Packit c4476c
#include <openssl/ecdh.h>
Packit c4476c
#include <openssl/fips.h>
Packit c4476c
#include <openssl/err.h>
Packit c4476c
#include <openssl/evp.h>
Packit c4476c
#include <openssl/bn.h>
Packit c4476c
Packit c4476c
#ifdef OPENSSL_FIPS
Packit c4476c
Packit c4476c
# include "fips_locl.h"
Packit c4476c
Packit c4476c
static const unsigned char p256_qcavsx[] = {
Packit c4476c
    0x52, 0xc6, 0xa5, 0x75, 0xf3, 0x04, 0x98, 0xb3, 0x29, 0x66, 0x0c, 0x62,
Packit c4476c
    0x18, 0x60, 0x55, 0x41, 0x59, 0xd4, 0x60, 0x85, 0x99, 0xc1, 0x51, 0x13,
Packit c4476c
    0x6f, 0x97, 0x85, 0x93, 0x33, 0x34, 0x07, 0x50
Packit c4476c
};
Packit c4476c
Packit c4476c
static const unsigned char p256_qcavsy[] = {
Packit c4476c
    0x6f, 0x69, 0x24, 0xeb, 0xe9, 0x3b, 0xa7, 0xcc, 0x47, 0x17, 0xaa, 0x3f,
Packit c4476c
    0x70, 0xfc, 0x10, 0x73, 0x0a, 0xcd, 0x21, 0xee, 0x29, 0x19, 0x1f, 0xaf,
Packit c4476c
    0xb4, 0x1c, 0x1e, 0xc2, 0x8e, 0x97, 0x81, 0x6e
Packit c4476c
};
Packit c4476c
Packit c4476c
static const unsigned char p256_qiutx[] = {
Packit c4476c
    0x71, 0x46, 0x88, 0x08, 0x92, 0x21, 0x1b, 0x10, 0x21, 0x74, 0xff, 0x0c,
Packit c4476c
    0x94, 0xde, 0x34, 0x7c, 0x86, 0x74, 0xbe, 0x67, 0x41, 0x68, 0xd4, 0xc1,
Packit c4476c
    0xe5, 0x75, 0x63, 0x9c, 0xa7, 0x46, 0x93, 0x6f
Packit c4476c
};
Packit c4476c
Packit c4476c
static const unsigned char p256_qiuty[] = {
Packit c4476c
    0x33, 0x40, 0xa9, 0x6a, 0xf5, 0x20, 0xb5, 0x9e, 0xfc, 0x60, 0x1a, 0xae,
Packit c4476c
    0x3d, 0xf8, 0x21, 0xd2, 0xa7, 0xca, 0x52, 0x34, 0xb9, 0x5f, 0x27, 0x75,
Packit c4476c
    0x6c, 0x81, 0xbe, 0x32, 0x4d, 0xba, 0xbb, 0xf8
Packit c4476c
};
Packit c4476c
Packit c4476c
static const unsigned char p256_qiutd[] = {
Packit c4476c
    0x1a, 0x48, 0x55, 0x6b, 0x11, 0xbe, 0x92, 0xd4, 0x1c, 0xd7, 0x45, 0xc3,
Packit c4476c
    0x82, 0x81, 0x51, 0xf1, 0x23, 0x40, 0xb7, 0x83, 0xfd, 0x01, 0x6d, 0xbc,
Packit c4476c
    0xa1, 0x66, 0xaf, 0x0a, 0x03, 0x23, 0xcd, 0xc8
Packit c4476c
};
Packit c4476c
Packit c4476c
static const unsigned char p256_ziut[] = {
Packit c4476c
    0x77, 0x2a, 0x1e, 0x37, 0xee, 0xe6, 0x51, 0x02, 0x71, 0x40, 0xf8, 0x6a,
Packit c4476c
    0x36, 0xf8, 0x65, 0x61, 0x2b, 0x18, 0x71, 0x82, 0x23, 0xe6, 0xf2, 0x77,
Packit c4476c
    0xce, 0xec, 0xb8, 0x49, 0xc7, 0xbf, 0x36, 0x4f
Packit c4476c
};
Packit c4476c
Packit c4476c
typedef struct {
Packit c4476c
    int curve;
Packit c4476c
    const unsigned char *x1;
Packit c4476c
    size_t x1len;
Packit c4476c
    const unsigned char *y1;
Packit c4476c
    size_t y1len;
Packit c4476c
    const unsigned char *d1;
Packit c4476c
    size_t d1len;
Packit c4476c
    const unsigned char *x2;
Packit c4476c
    size_t x2len;
Packit c4476c
    const unsigned char *y2;
Packit c4476c
    size_t y2len;
Packit c4476c
    const unsigned char *z;
Packit c4476c
    size_t zlen;
Packit c4476c
} ECDH_SELFTEST_DATA;
Packit c4476c
Packit c4476c
# define make_ecdh_test(nid, pr) { nid, \
Packit c4476c
                                pr##_qiutx, sizeof(pr##_qiutx), \
Packit c4476c
                                pr##_qiuty, sizeof(pr##_qiuty), \
Packit c4476c
                                pr##_qiutd, sizeof(pr##_qiutd), \
Packit c4476c
                                pr##_qcavsx, sizeof(pr##_qcavsx), \
Packit c4476c
                                pr##_qcavsy, sizeof(pr##_qcavsy), \
Packit c4476c
                                pr##_ziut, sizeof(pr##_ziut) }
Packit c4476c
Packit c4476c
static ECDH_SELFTEST_DATA test_ecdh_data[] = {
Packit c4476c
    make_ecdh_test(NID_X9_62_prime256v1, p256),
Packit c4476c
};
Packit c4476c
Packit c4476c
int FIPS_selftest_ecdh(void)
Packit c4476c
{
Packit c4476c
    EC_KEY *ec1 = NULL, *ec2 = NULL;
Packit c4476c
    const EC_POINT *ecp = NULL;
Packit c4476c
    BIGNUM *x = NULL, *y = NULL, *d = NULL;
Packit c4476c
    unsigned char *ztmp = NULL;
Packit c4476c
    int rv = 1;
Packit c4476c
    size_t i;
Packit c4476c
Packit c4476c
    for (i = 0; i < sizeof(test_ecdh_data) / sizeof(ECDH_SELFTEST_DATA); i++) {
Packit c4476c
        ECDH_SELFTEST_DATA *ecd = test_ecdh_data + i;
Packit c4476c
        if (!fips_post_started(FIPS_TEST_ECDH, ecd->curve, 0))
Packit c4476c
            continue;
Packit c4476c
        ztmp = OPENSSL_malloc(ecd->zlen);
Packit c4476c
Packit c4476c
        x = BN_bin2bn(ecd->x1, ecd->x1len, x);
Packit c4476c
        y = BN_bin2bn(ecd->y1, ecd->y1len, y);
Packit c4476c
        d = BN_bin2bn(ecd->d1, ecd->d1len, d);
Packit c4476c
Packit c4476c
        if (!x || !y || !d || !ztmp) {
Packit c4476c
            rv = 0;
Packit c4476c
            goto err;
Packit c4476c
        }
Packit c4476c
Packit c4476c
        ec1 = EC_KEY_new_by_curve_name(ecd->curve);
Packit c4476c
        if (!ec1) {
Packit c4476c
            rv = 0;
Packit c4476c
            goto err;
Packit c4476c
        }
Packit c4476c
        EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH);
Packit c4476c
Packit c4476c
        if (!EC_KEY_set_public_key_affine_coordinates(ec1, x, y)) {
Packit c4476c
            rv = 0;
Packit c4476c
            goto err;
Packit c4476c
        }
Packit c4476c
Packit c4476c
        if (!EC_KEY_set_private_key(ec1, d)) {
Packit c4476c
            rv = 0;
Packit c4476c
            goto err;
Packit c4476c
        }
Packit c4476c
Packit c4476c
        x = BN_bin2bn(ecd->x2, ecd->x2len, x);
Packit c4476c
        y = BN_bin2bn(ecd->y2, ecd->y2len, y);
Packit c4476c
Packit c4476c
        if (!x || !y) {
Packit c4476c
            rv = 0;
Packit c4476c
            goto err;
Packit c4476c
        }
Packit c4476c
Packit c4476c
        ec2 = EC_KEY_new_by_curve_name(ecd->curve);
Packit c4476c
        if (!ec2) {
Packit c4476c
            rv = 0;
Packit c4476c
            goto err;
Packit c4476c
        }
Packit c4476c
        EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH);
Packit c4476c
Packit c4476c
        if (!EC_KEY_set_public_key_affine_coordinates(ec2, x, y)) {
Packit c4476c
            rv = 0;
Packit c4476c
            goto err;
Packit c4476c
        }
Packit c4476c
Packit c4476c
        ecp = EC_KEY_get0_public_key(ec2);
Packit c4476c
        if (!ecp) {
Packit c4476c
            rv = 0;
Packit c4476c
            goto err;
Packit c4476c
        }
Packit c4476c
Packit c4476c
        if (!ECDH_compute_key(ztmp, ecd->zlen, ecp, ec1, 0)) {
Packit c4476c
            rv = 0;
Packit c4476c
            goto err;
Packit c4476c
        }
Packit c4476c
Packit c4476c
        if (!fips_post_corrupt(FIPS_TEST_ECDH, ecd->curve, NULL))
Packit c4476c
            ztmp[0] ^= 0x1;
Packit c4476c
Packit c4476c
        if (memcmp(ztmp, ecd->z, ecd->zlen)) {
Packit c4476c
            fips_post_failed(FIPS_TEST_ECDH, ecd->curve, 0);
Packit c4476c
            rv = 0;
Packit c4476c
        } else if (!fips_post_success(FIPS_TEST_ECDH, ecd->curve, 0))
Packit c4476c
            goto err;
Packit c4476c
Packit c4476c
        EC_KEY_free(ec1);
Packit c4476c
        ec1 = NULL;
Packit c4476c
        EC_KEY_free(ec2);
Packit c4476c
        ec2 = NULL;
Packit c4476c
        OPENSSL_free(ztmp);
Packit c4476c
        ztmp = NULL;
Packit c4476c
    }
Packit c4476c
Packit c4476c
 err:
Packit c4476c
Packit c4476c
    if (x)
Packit c4476c
        BN_clear_free(x);
Packit c4476c
    if (y)
Packit c4476c
        BN_clear_free(y);
Packit c4476c
    if (d)
Packit c4476c
        BN_clear_free(d);
Packit c4476c
    if (ec1)
Packit c4476c
        EC_KEY_free(ec1);
Packit c4476c
    if (ec2)
Packit c4476c
        EC_KEY_free(ec2);
Packit c4476c
    if (ztmp)
Packit c4476c
        OPENSSL_free(ztmp);
Packit c4476c
Packit c4476c
    return rv;
Packit c4476c
Packit c4476c
}
Packit c4476c
Packit c4476c
#endif