Blame crypto/hmac/hm_ameth.c

Packit c4476c
/*
Packit c4476c
 * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved.
Packit c4476c
 *
Packit c4476c
 * Licensed under the OpenSSL license (the "License").  You may not use
Packit c4476c
 * this file except in compliance with the License.  You can obtain a copy
Packit c4476c
 * in the file LICENSE in the source distribution or at
Packit c4476c
 * https://www.openssl.org/source/license.html
Packit c4476c
 */
Packit c4476c
Packit c4476c
#include <stdio.h>
Packit c4476c
#include "internal/cryptlib.h"
Packit c4476c
#include <openssl/evp.h>
Packit c4476c
#include "crypto/asn1.h"
Packit c4476c
#include "crypto/evp.h"
Packit c4476c
Packit c4476c
/*
Packit c4476c
 * HMAC "ASN1" method. This is just here to indicate the maximum HMAC output
Packit c4476c
 * length and to free up an HMAC key.
Packit c4476c
 */
Packit c4476c
Packit c4476c
static int hmac_size(const EVP_PKEY *pkey)
Packit c4476c
{
Packit c4476c
    return EVP_MAX_MD_SIZE;
Packit c4476c
}
Packit c4476c
Packit c4476c
static void hmac_key_free(EVP_PKEY *pkey)
Packit c4476c
{
Packit c4476c
    ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey);
Packit c4476c
    if (os) {
Packit c4476c
        if (os->data)
Packit c4476c
            OPENSSL_cleanse(os->data, os->length);
Packit c4476c
        ASN1_OCTET_STRING_free(os);
Packit c4476c
    }
Packit c4476c
}
Packit c4476c
Packit c4476c
static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
Packit c4476c
{
Packit c4476c
    switch (op) {
Packit c4476c
    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
Packit c4476c
        *(int *)arg2 = NID_sha256;
Packit c4476c
        return 1;
Packit c4476c
Packit c4476c
    default:
Packit c4476c
        return -2;
Packit c4476c
    }
Packit c4476c
}
Packit c4476c
Packit c4476c
static int hmac_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
Packit c4476c
{
Packit c4476c
    return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b));
Packit c4476c
}
Packit c4476c
Packit c4476c
static int hmac_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
Packit c4476c
                             size_t len)
Packit c4476c
{
Packit c4476c
    ASN1_OCTET_STRING *os;
Packit c4476c
Packit c4476c
    if (pkey->pkey.ptr != NULL)
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    os = ASN1_OCTET_STRING_new();
Packit c4476c
    if (os == NULL)
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
Packit c4476c
    if (!ASN1_OCTET_STRING_set(os, priv, len)) {
Packit c4476c
        ASN1_OCTET_STRING_free(os);
Packit c4476c
        return 0;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    pkey->pkey.ptr = os;
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
static int hmac_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
Packit c4476c
                             size_t *len)
Packit c4476c
{
Packit c4476c
    ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
Packit c4476c
Packit c4476c
    if (priv == NULL) {
Packit c4476c
        *len = ASN1_STRING_length(os);
Packit c4476c
        return 1;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    if (os == NULL || *len < (size_t)ASN1_STRING_length(os))
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    *len = ASN1_STRING_length(os);
Packit c4476c
    memcpy(priv, ASN1_STRING_get0_data(os), *len);
Packit c4476c
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
Packit c4476c
    EVP_PKEY_HMAC,
Packit c4476c
    EVP_PKEY_HMAC,
Packit c4476c
    0,
Packit c4476c
Packit c4476c
    "HMAC",
Packit c4476c
    "OpenSSL HMAC method",
Packit c4476c
Packit c4476c
    0, 0, hmac_pkey_public_cmp, 0,
Packit c4476c
Packit c4476c
    0, 0, 0,
Packit c4476c
Packit c4476c
    hmac_size,
Packit c4476c
    0, 0,
Packit c4476c
    0, 0, 0, 0, 0, 0, 0,
Packit c4476c
Packit c4476c
    hmac_key_free,
Packit c4476c
    hmac_pkey_ctrl,
Packit c4476c
    NULL,
Packit c4476c
    NULL,
Packit c4476c
Packit c4476c
    NULL,
Packit c4476c
    NULL,
Packit c4476c
    NULL,
Packit c4476c
Packit c4476c
    NULL,
Packit c4476c
    NULL,
Packit c4476c
    NULL,
Packit c4476c
Packit c4476c
    hmac_set_priv_key,
Packit c4476c
    NULL,
Packit c4476c
    hmac_get_priv_key,
Packit c4476c
    NULL,
Packit c4476c
};