Example devcrypto plugin: openssl_digest.c
QNX SDP8.0QNX OS System Security GuideAPIConfiguration
This example illustrates how to implement a devcrypto plugin.
For more information, see The
devcrypto plugin API
(devcrypto_plugin.h
) and the entry for devcrypto in the Utilities Reference.
/*
* $QNXLicenseC:
* Copyright 2018, QNX Software Systems. All Rights Reserved.
*
* You must obtain a written license from and pay applicable license fees to QNX
* Software Systems before you may reproduce, modify or distribute this software,
* or any work that includes all or part of this software. Free development
* licenses are available for evaluation and non-commercial purposes. For more
* information visit http://licensing.qnx.com or email licensing@qnx.com.
*
* This file may contain contributions from others. Please review this entire
* file for other proprietary rights or license notices, as well as the QNX
* Development Suite License Guide at http://licensing.qnx.com/license-guide/
* for other information.
* $
*/
#include <errno.h>
#include <stdlib.h>
#include <crypto/devcrypto_plugin.h>
#include <openssl/evp.h>
#include "openssl.h"
/*
* Openssl digest context
*/
typedef struct _digest_ctx
{
const EVP_MD *md; /* digest algorithm */
EVP_MD_CTX *mdctx; /* digest context */
} digest_ctx;
/*
* Openssl digest algorithm initialization
*
* @sctx: state context object
* @alg: algorithm object
*
* Return:
* - EOK on success
* - errno on failure
*/
static int devcrypto_openssl_digest_alg_init(devcrypto_state_ctx_t *sctx)
{
int ret = EOK;
digest_ctx *ctx;
ctx = calloc(1, sizeof(*ctx));
if (!ctx) {
ret = ENOMEM;
goto done;
}
ctx->md = EVP_get_digestbyname(sctx->alg->name);
if (!ctx->md) {
ret = ELIBBAD;
goto err;
}
ctx->mdctx = EVP_MD_CTX_create();
if (!ctx->mdctx) {
ret = ENOMEM;
goto err;
}
sctx->data = ctx;
ret = EOK;
goto done;
err:
free(ctx);
done:
return ret;
}
/*
* Openssl digest algorithm un-initialization
*
* @sctx: state context object
*
* Return:
* - EOK on success
*/
static void devcrypto_openssl_digest_alg_uninit(devcrypto_state_ctx_t *sctx)
{
digest_ctx *ctx = sctx->data;
EVP_MD_CTX_destroy(ctx->mdctx);
free(ctx);
}
/*
* Openssl Digest Init
*
* @sctx: state context object
*
* Return:
* - EOK on success
* - errno on failure
*/
static int devcrypto_openssl_digest_init(devcrypto_state_ctx_t *sctx)
{
int ret;
digest_ctx *ctx = sctx->data;
ret = EVP_DigestInit(ctx->mdctx, ctx->md);
if (ret <= 0) {
return ELIBBAD;
}
return EOK;
}
/*
* Openssl Digest Update
*
* @sctx: state context object
* @data: binary data to hash in digest
* @size: size of @data
*
* Return:
* - EOK on success
* - errno on failure
*/
static int devcrypto_openssl_digest_update(devcrypto_state_ctx_t *sctx, const uint8_t *data, uint32_t size)
{
int ret;
digest_ctx *ctx = sctx->data;
ret = EVP_DigestUpdate(ctx->mdctx, data, size);
if (ret <= 0) {
return ELIBBAD;
}
return EOK;
}
/*
* Openssl Digest Init
*
* @sctx: state context object
* @digest: buffer to store digest value
* @size: pointer to store digest size
*
* Return:
* - EOK on success
* - errno on failure
*/
static int devcrypto_openssl_digest_final(devcrypto_state_ctx_t *sctx, uint8_t *digest, uint32_t *size)
{
int ret;
digest_ctx *ctx = sctx->data;
unsigned int dsize;
ret = EVP_DigestFinal(ctx->mdctx, digest, &dsize);
if (ret <= 0) {
return ELIBBAD;
}
if (size) {
*size = (uint32_t)dsize;
}
return EOK;
}
/* Algorithms */
/*
* Digests
*/
#define OPENSSL_DIGEST_ALG(dgstname, dgst, DGST) \
static const devcrypto_algorithm_t dgst = { \
.name = dgstname, \
.type = CRYPTO_ ## DGST, \
.init = devcrypto_openssl_digest_alg_init, \
.uninit = devcrypto_openssl_digest_alg_uninit, \
.digest = { \
.params = { \
.digestsize = DGST ## _DIGEST_SIZE, \
.blocksize = DGST ## _BLOCK_SIZE, \
}, \
.ops = { \
.init = devcrypto_openssl_digest_init, \
.update = devcrypto_openssl_digest_update,\
.final = devcrypto_openssl_digest_final, \
}, \
}, \
};
/* Define algorithms */
OPENSSL_DIGEST_ALG("md5",md5,MD5)
OPENSSL_DIGEST_ALG("sha1",sha1,SHA1)
OPENSSL_DIGEST_ALG("sha224",sha224,SHA224)
OPENSSL_DIGEST_ALG("sha256",sha256,SHA256)
OPENSSL_DIGEST_ALG("sha384",sha384,SHA384)
OPENSSL_DIGEST_ALG("sha512",sha512,SHA512)
OPENSSL_DIGEST_ALG("sha512-224",sha512_224,SHA512_224)
OPENSSL_DIGEST_ALG("sha512-256",sha512_256,SHA512_256)
/*
* TODO
*/
void devcrypto_openssl_digest_register(void)
{
devcrypto_plugin_register_algorithm(&md5);
devcrypto_plugin_register_algorithm(&sha1);
devcrypto_plugin_register_algorithm(&sha224);
devcrypto_plugin_register_algorithm(&sha256);
devcrypto_plugin_register_algorithm(&sha384);
devcrypto_plugin_register_algorithm(&sha512);
devcrypto_plugin_register_algorithm(&sha512_224);
devcrypto_plugin_register_algorithm(&sha512_256);
}
Page updated: