コード例 #1
0
BUF_MEM *
add_iso_pad(const BUF_MEM * m, int block_size)
{
    BUF_MEM * out = NULL;
    int p_len;

    check(m, "Invalid arguments");

    /* calculate length of padded message */
    p_len = (m->length / block_size) * block_size + block_size;

    out = BUF_MEM_create(p_len);
    if (!out)
        goto err;

    /* Flawfinder: ignore */
    memcpy(out->data, m->data, m->length);

    /* now add iso padding */
    memset(out->data + m->length, 0x80, 1);
    memset(out->data + m->length + 1, 0, p_len - m->length - 1);

err:
    return out;
}
コード例 #2
0
static BUF_MEM *
cipher(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl,
        const unsigned char *key, const unsigned char *iv, int enc, const BUF_MEM * in)
{
    BUF_MEM * out = NULL;
    EVP_CIPHER_CTX * tmp_ctx = NULL;
    int i;
    unsigned long flags;

    check(in, "Invalid arguments");

    if (ctx)
        tmp_ctx = ctx;
    else {
        tmp_ctx = EVP_CIPHER_CTX_new();
        if (!tmp_ctx)
            goto err;
        EVP_CIPHER_CTX_init(tmp_ctx);
        if (!EVP_CipherInit_ex(tmp_ctx, type, impl, key, iv, enc))
            goto err;
    }

    flags = EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(tmp_ctx));

    if (flags & EVP_CIPH_NO_PADDING) {
        i = in->length;
        check((in->length % EVP_CIPHER_block_size(type) == 0), "Data is not of blocklength");
    } else
        i = in->length + EVP_CIPHER_block_size(type);

    out = BUF_MEM_create(i);
    if (!out)
        goto err;

    if (!EVP_CipherUpdate(tmp_ctx, (unsigned char *) out->data, &i,
            (unsigned char *) in->data, in->length))
        goto err;
    out->length = i;

    if (!EVP_CipherFinal_ex(tmp_ctx, (unsigned char *) (out->data + out->length),
            &i))
            goto err;

    if (!(flags & EVP_CIPH_NO_PADDING))
        out->length += i;

    if (!ctx)
        EVP_CIPHER_CTX_free(tmp_ctx);

    return out;

err:

    if (out)
        BUF_MEM_free(out);
    if (!ctx && tmp_ctx)
        EVP_CIPHER_CTX_free(tmp_ctx);

    return NULL;
}
コード例 #3
0
BUF_MEM *
cmac(CMAC_CTX *ctx, const EVP_CIPHER *type, const BUF_MEM * key,
        const BUF_MEM * in, size_t maclen)
{
    CMAC_CTX * cmac_ctx = NULL;
    BUF_MEM * out = NULL, * tmp = NULL;
    size_t cmac_len = 0;

    check((key && in && type), "Invalid arguments");

    check((key->length >= (size_t) EVP_CIPHER_key_length(type)),
            "Key is too short");

    if (ctx)
        cmac_ctx = ctx;
    else {
        cmac_ctx = CMAC_CTX_new();
    }

    /* Initialize the CMAC context, feed in the data, and get the required
     * output buffer size */
    if (!cmac_ctx ||
            !CMAC_Init(cmac_ctx, key->data, EVP_CIPHER_key_length(type),
                type, NULL) ||
            !CMAC_Update(cmac_ctx, in->data, in->length) ||
            !CMAC_Final(cmac_ctx, NULL, &cmac_len))
        goto err;

    /* get buffer in required size */
    out = BUF_MEM_create(cmac_len);
    if (!out)
        goto err;

    /* get the actual CMAC */
    if (!CMAC_Final(cmac_ctx, (unsigned char*) out->data, &out->length))
        goto err;

    /* Truncate the CMAC if necessary */
    if (cmac_len > maclen) {
        tmp = BUF_MEM_create_init(out->data, maclen);
        BUF_MEM_free(out);
        out = tmp;
    }

    if (!ctx)
        CMAC_CTX_free(cmac_ctx);

    return out;

err:
    if (cmac_ctx && !ctx) {
        CMAC_CTX_free(cmac_ctx);
    }
    if (out) {
        BUF_MEM_free(out);
    }

    return NULL;
}
コード例 #4
0
BUF_MEM *
Comp(EVP_PKEY *key, const BUF_MEM *pub, BN_CTX *bn_ctx, EVP_MD_CTX *md_ctx)
{
    BUF_MEM *out = NULL;
    const EC_GROUP *group;
    EC_POINT *ecp = NULL;
    EC_KEY *ec = NULL;
    BIGNUM *x = NULL, *y = NULL;

    check((key && pub), "Invalid arguments");

    switch (EVP_PKEY_base_id(key)) {
        case EVP_PKEY_DH:
            out = hash(EVP_sha1(), md_ctx, NULL, pub);
            break;

        case EVP_PKEY_EC:
            ec = EVP_PKEY_get1_EC_KEY(key);
            if (!ec)
                goto err;

            group = EC_KEY_get0_group(ec);
            ecp = EC_POINT_new(group);
            x = BN_CTX_get(bn_ctx);
            y = BN_CTX_get(bn_ctx);

            if(!ecp || !x || !y
                    || !EC_POINT_oct2point(group, ecp,
                        (unsigned char *) pub->data, pub->length, bn_ctx)
                    || !EC_POINT_get_affine_coordinates_GF2m(group, ecp, x, y, bn_ctx))
                goto err;

            out = BUF_MEM_create(BN_num_bytes(x));
            if(!out || !BN_bn2bin(x, (unsigned char *) out->data))
                goto err;
            break;

        default:
            log_err("Unknown protocol");
            goto err;
    }

err:
    if (ecp)
        EC_POINT_free(ecp);
    /* Decrease the reference count, the key is still available in the EVP_PKEY
     * structure */
    if (ec)
        EC_KEY_free(ec);
    if (x)
        BN_free(x);
    if (y)
        BN_free(y);

    return out;
}
コード例 #5
0
ファイル: misc.c プロジェクト: RushOnline/openpace
BUF_MEM *
BUF_MEM_create_init(const void *buf, size_t len)
{
    BUF_MEM *out;

    out = BUF_MEM_create(len);
    if (!out)
        return NULL;

    memcpy(out->data, buf, len);

    return out;
}
コード例 #6
0
ファイル: misc.c プロジェクト: RushOnline/openpace
BUF_MEM *
BN_bn2buf(const BIGNUM *bn)
{
    BUF_MEM * out;

    if (!bn)
        return NULL;

    out = BUF_MEM_create(BN_num_bytes(bn));
    if (!out)
        return NULL;

    out->length = BN_bn2bin(bn, (unsigned char *) out->data);

    return out;
}
コード例 #7
0
ファイル: misc.c プロジェクト: RushOnline/openpace
BUF_MEM *
BUF_MEM_dup(const BUF_MEM * in)
{
    BUF_MEM * out = NULL;

    if (!in)
        return NULL;

    out = BUF_MEM_create(in->length);
    check(out, "Failed to allocate memory");

    memcpy(out->data, in->data, in->length);
    out->max = in->max;

err:
    return out;
}
コード例 #8
0
BUF_MEM *
dh_compute_key(EVP_PKEY *key, const BUF_MEM * in, BN_CTX *bn_ctx)
{
    BUF_MEM * out = NULL;
    BIGNUM * bn = NULL;
    DH *dh = NULL;

    check(key && in, "Invalid arguments");

    dh = EVP_PKEY_get1_DH(key);
    if (!dh)
        return NULL;

    /* decode public key */
    bn = BN_bin2bn((unsigned char *) in->data, in->length, bn);
    if (!bn)
        goto err;

    out = BUF_MEM_create(DH_size(dh));
    if (!out)
        goto err;

    out->length = DH_compute_key((unsigned char *) out->data, bn, dh);
    if ((int) out->length < 0)
        goto err;

    BN_clear_free(bn);
    DH_free(dh);

    return out;

err:
    if (out)
        BUF_MEM_free(out);
    if (bn)
        BN_clear_free(bn);
    if (dh)
        DH_free(dh);

    return NULL;
}
コード例 #9
0
ファイル: misc.c プロジェクト: RushOnline/openpace
BUF_MEM *
EC_POINT_point2buf(const EC_KEY * ecdh, BN_CTX * bn_ctx, const EC_POINT * ecp)
{
    size_t len;
    BUF_MEM * out;

    len = EC_POINT_point2oct(EC_KEY_get0_group(ecdh), ecp,
            EC_KEY_get_conv_form(ecdh), NULL, 0, bn_ctx);
    if (len == 0)
        return NULL;

    out = BUF_MEM_create(len);
    if (!out)
        return NULL;

    out->length = EC_POINT_point2oct(EC_KEY_get0_group(ecdh), ecp,
            EC_KEY_get_conv_form(ecdh), (unsigned char *) out->data, out->max,
            bn_ctx);

    return out;
}
コード例 #10
0
BUF_MEM *
hash(const EVP_MD * md, EVP_MD_CTX * ctx, ENGINE * impl, const BUF_MEM * in)
{
    BUF_MEM * out = NULL;
    EVP_MD_CTX * tmp_ctx = NULL;
    unsigned int tmp_len;

    check((md && in), "Invalid arguments");

    if (ctx)
        tmp_ctx = ctx;
    else {
        tmp_ctx = EVP_MD_CTX_create();
        if (!tmp_ctx)
            goto err;
    }

    tmp_len = EVP_MD_size(md);
    out = BUF_MEM_create(tmp_len);
    if (!out || !EVP_DigestInit_ex(tmp_ctx, md, impl) ||
            !EVP_DigestUpdate(tmp_ctx, in->data, in->length) ||
            !EVP_DigestFinal_ex(tmp_ctx, (unsigned char *) out->data,
                &tmp_len))
        goto err;
    out->length = tmp_len;

    if (!ctx)
        EVP_MD_CTX_destroy(tmp_ctx);

    return out;

err:
    if (out)
        BUF_MEM_free(out);
    if (tmp_ctx && !ctx)
        EVP_MD_CTX_destroy(tmp_ctx);

    return NULL;
}
コード例 #11
0
BUF_MEM *
EAC_sign(int protocol, EVP_PKEY *key, const BUF_MEM *data)
{
    BUF_MEM *signature = NULL, *signature_data = NULL, *plain_sig = NULL;
    EVP_PKEY_CTX *tmp_key_ctx = NULL;
    size_t len;
    const EVP_MD *md = eac_oid2md(protocol);
    int type;

    check((key && data), "Invalid arguments");

    tmp_key_ctx = EVP_PKEY_CTX_new(key, NULL);
    if (!tmp_key_ctx || !md
               || EVP_PKEY_sign_init(tmp_key_ctx) <= 0
            || EVP_PKEY_CTX_set_signature_md(tmp_key_ctx, md) <= 0)
        goto err;


    type = EVP_PKEY_base_id(key);
    if (       protocol == NID_id_TA_ECDSA_SHA_1
            || protocol == NID_id_TA_ECDSA_SHA_224
            || protocol == NID_id_TA_ECDSA_SHA_256
            || protocol == NID_id_TA_ECDSA_SHA_384
            || protocol == NID_id_TA_ECDSA_SHA_512) {
        if (!(type == EVP_PKEY_EC))
            goto err;

    } else if (protocol == NID_id_TA_RSA_v1_5_SHA_1
            || protocol == NID_id_TA_RSA_v1_5_SHA_256
            || protocol == NID_id_TA_RSA_v1_5_SHA_512) {
        if (!(type == EVP_PKEY_RSA))
            goto err;

        if (!EVP_PKEY_CTX_set_rsa_padding(tmp_key_ctx, RSA_PKCS1_PADDING))
            goto err;

    } else if (protocol == NID_id_TA_RSA_PSS_SHA_1
            || protocol == NID_id_TA_RSA_PSS_SHA_256
            || protocol == NID_id_TA_RSA_PSS_SHA_512) {
        if (!(type == EVP_PKEY_RSA))
            goto err;

        if (!EVP_PKEY_CTX_set_rsa_padding(tmp_key_ctx, RSA_PKCS1_PSS_PADDING))
            goto err;

    } else {
        goto err;
    }

    /* EVP_PKEY_sign doesn't perform hashing (despite EVP_PKEY_CTX_set_signature_md).
     * Therefore we need to compute the hash ourself. */
    signature_data = hash(md, NULL, NULL, data);
    if (!signature_data)
        goto err;


    /* Actual signature creation */
    if (EVP_PKEY_sign(tmp_key_ctx, NULL, &len,
               (unsigned char*) signature_data->data,
               signature_data->length) <= 0)
        goto err;
    signature = BUF_MEM_create(len);
    if (!signature)
        goto err;
    if (EVP_PKEY_sign(tmp_key_ctx,
                (unsigned char *) signature->data,
                &signature->length,
                (unsigned char*) signature_data->data,
                signature_data->length) <= 0)
        goto err;


    /* EAC signatures are always in plain signature format for EC curves but
     * OpenSSL only creates X.509 format. Therefore we need to convert between
     * these formats. */
    if (       protocol == NID_id_TA_ECDSA_SHA_1
            || protocol == NID_id_TA_ECDSA_SHA_224
            || protocol == NID_id_TA_ECDSA_SHA_256
            || protocol == NID_id_TA_ECDSA_SHA_384
            || protocol == NID_id_TA_ECDSA_SHA_512) {
        plain_sig = convert_to_plain_sig(signature);
        BUF_MEM_free(signature);
        signature = plain_sig;
    }

err:
    if (tmp_key_ctx)
        EVP_PKEY_CTX_free(tmp_key_ctx);
    if (signature_data)
        BUF_MEM_free(signature_data);

    return signature;
}
コード例 #12
0
BUF_MEM *
convert_to_plain_sig(const BUF_MEM *x962_sig)
{
    size_t r_len, s_len, rs_max;
    BUF_MEM *plain_sig_buf = NULL;
    ECDSA_SIG *tmp_sig = NULL;
    const unsigned char *tmp;
    unsigned char *r = NULL, *s = NULL;
    const BIGNUM *bn_r, *bn_s;

    check_return(x962_sig, "Invalid arguments");

    /* Convert the ASN.1 data to a C structure*/
    tmp = (unsigned char*) x962_sig->data;
    tmp_sig = ECDSA_SIG_new();
    if (!tmp_sig)
        goto err;
    if (!d2i_ECDSA_SIG(&tmp_sig, &tmp, x962_sig->length))
        goto err;

    ECDSA_SIG_get0(tmp_sig, &bn_r, &bn_s);

    /* Extract the parameters r and s*/
    r_len = BN_num_bytes(bn_r);
    s_len = BN_num_bytes(bn_s);
    rs_max = r_len > s_len ? r_len : s_len;
    r = OPENSSL_malloc(rs_max);
    s = OPENSSL_malloc(rs_max);
    if (!r || !s)
        goto err;

    /* Convert r and s to a binary representation */
    if (!BN_bn2bin(bn_r, r + rs_max - r_len))
        goto err;
    if (!BN_bn2bin(bn_s, s + rs_max - s_len))
        goto err;
    /* r and s must be padded with leading zero bytes to ensure they have the
     * same length */
    memset(r, 0, rs_max - r_len);
    memset(s, 0, rs_max - s_len);

    /* concatenate r and s to get the plain signature format */
    plain_sig_buf = BUF_MEM_create(rs_max + rs_max);
    if (!plain_sig_buf)
        goto err;
    memcpy(plain_sig_buf->data, r, rs_max);
    memcpy(plain_sig_buf->data + rs_max, s, rs_max);

    OPENSSL_free(r);
    OPENSSL_free(s);
    ECDSA_SIG_free(tmp_sig);

    return plain_sig_buf;

err:
    if (r)
        OPENSSL_free(r);
    if (s)
        OPENSSL_free(s);
    if (tmp_sig)
        ECDSA_SIG_free(tmp_sig);
    return NULL;
}