Tizen Native API  3.0
YACA Integrity

Provides APIs for creating/verifying a signature and digesting a message.

Required Header

#include <yaca/yaca_sign.h>
#include <yaca/yaca_digest.h>

Overview

It provides advanced APIs for creating a signature using asymmetric private key, verifying a signature using asymmetric public key, calculating a HMAC/CMAC of given message using symmetric key and calculating message digests of given message without key.

Examples

Message Digest API example

#include <stdio.h>

#include <yaca_crypto.h>
#include <yaca_digest.h>
#include <yaca_error.h>

/* include helpers functions and definitions */
#include "misc.h"

int main()
{
    int ret;
    yaca_context_h ctx = YACA_CONTEXT_NULL;

    ret = yaca_initialize();
    if (ret != YACA_ERROR_NONE)
        goto exit;

    printf("Plain data (16 of %zu bytes): %.16s\n", INPUT_DATA_SIZE, INPUT_DATA);

    /* Initialize digest context */
    ret = yaca_digest_initialize(&ctx, YACA_DIGEST_SHA256);
    if (ret != YACA_ERROR_NONE)
        goto exit;

    /* Feeds the message */
    ret = yaca_digest_update(ctx, INPUT_DATA, INPUT_DATA_SIZE);
    if (ret != YACA_ERROR_NONE)
        goto exit;

    /* Get digest length */
    size_t digest_len;
    ret = yaca_context_get_output_length(ctx, 0, &digest_len);
    if (ret != YACA_ERROR_NONE)
        goto exit;

    /* Calculate digest */
    {
        char digest[digest_len];
        ret = yaca_digest_finalize(ctx, digest, &digest_len);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* display digest in hexadecimal format */
        dump_hex(digest, digest_len, "Message digest: ");
    }

exit:
    yaca_context_destroy(ctx);

    yaca_cleanup();
    return ret;
}

Signature API example

#include <stdio.h>

#include <yaca_crypto.h>
#include <yaca_sign.h>
#include <yaca_key.h>
#include <yaca_error.h>

/* include helpers functions and definitions */
#include "misc.h"

int main()
{
    int ret;
    yaca_context_h ctx = YACA_CONTEXT_NULL;
    yaca_key_h priv_key = YACA_KEY_NULL;
    yaca_key_h pub_key = YACA_KEY_NULL;
    yaca_padding_e padding = YACA_PADDING_PKCS1_PSS;

    char *signature = NULL;
    size_t signature_len;

    ret = yaca_initialize();
    if (ret != YACA_ERROR_NONE)
        goto exit;

    /* Generate key pair */
    ret = yaca_key_generate(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_2048BIT, &priv_key);
    if (ret != YACA_ERROR_NONE)
        goto exit;

    ret = yaca_key_extract_public(priv_key, &pub_key);
    if (ret != YACA_ERROR_NONE)
        goto exit;

    /* Sign */
    {
        /* Initialize sign context */
        ret = yaca_sign_initialize(&ctx, YACA_DIGEST_SHA256, priv_key);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Set padding method */
        ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &padding, sizeof(padding));
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Feeds the message */
        ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Get signature length and allocate memory */
        ret = yaca_context_get_output_length(ctx, 0, &signature_len);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        ret = yaca_malloc(signature_len, (void**)&signature);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Calculate signature */
        ret = yaca_sign_finalize(ctx, signature, &signature_len);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* display signature in hexadecimal format */
        dump_hex(signature, signature_len, "Signature of INPUT_DATA:");

        yaca_context_destroy(ctx);
        ctx = YACA_CONTEXT_NULL;
    }

    /* Verify */
    {
        /* Initialize verify context */
        ret = yaca_verify_initialize(&ctx, YACA_DIGEST_SHA256, pub_key);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Set padding method */
        ret = yaca_context_set_property(ctx, YACA_PROPERTY_PADDING, &padding, sizeof(padding));
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Feeds the message */
        ret = yaca_verify_update(ctx, INPUT_DATA, INPUT_DATA_SIZE);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Verify signature */
        ret = yaca_verify_finalize(ctx, signature, signature_len);
        if (ret != YACA_ERROR_NONE) {
            printf("Verification failed\n");
            goto exit;
        } else {
            printf("Verification successful\n");
        }
    }

exit:
    yaca_free(signature);
    yaca_key_destroy(priv_key);
    yaca_key_destroy(pub_key);
    yaca_context_destroy(ctx);

    yaca_cleanup();
    return ret;
}

HMAC Signature API example

#include <stdio.h>

#include <yaca_crypto.h>
#include <yaca_sign.h>
#include <yaca_key.h>
#include <yaca_error.h>

/* include helpers functions and definitions */
#include "misc.h"

int main()
{
    int ret;
    yaca_context_h ctx = YACA_CONTEXT_NULL;
    yaca_key_h sym_key = YACA_KEY_NULL;

    char *signature1 = NULL;
    char *signature2 = NULL;
    size_t signature_len;

    ret = yaca_initialize();
    if (ret != YACA_ERROR_NONE)
        goto exit;

    /* Key generation */
    ret = yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, YACA_KEY_LENGTH_256BIT, &sym_key);
    if (ret != YACA_ERROR_NONE)
        goto exit;

    /* Sign */
    {
        /* Initialize sign context */
        ret = yaca_sign_initialize_hmac(&ctx, YACA_DIGEST_SHA512, sym_key);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Feeds the message */
        ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Get signature length and allocate memory */
        ret = yaca_context_get_output_length(ctx, 0, &signature_len);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        ret = yaca_malloc(signature_len, (void**)&signature1);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Calculate signature */
        ret = yaca_sign_finalize(ctx, signature1, &signature_len);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* display signature in hexadecimal format */
        dump_hex(signature1, signature_len, "HMAC Signature of INPUT_DATA:");

        yaca_context_destroy(ctx);
        ctx = YACA_CONTEXT_NULL;
    }

    /* Verify */
    {
        /* Initialize sign context */
        ret = yaca_sign_initialize_hmac(&ctx, YACA_DIGEST_SHA512, sym_key);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Feeds the message */
        ret = yaca_sign_update(ctx, INPUT_DATA, INPUT_DATA_SIZE);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Get signature length and allocate memory */
        ret = yaca_context_get_output_length(ctx, 0, &signature_len);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        ret = yaca_malloc(signature_len, (void**)&signature2);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Calculate signature */
        ret = yaca_sign_finalize(ctx, signature2, &signature_len);
        if (ret != YACA_ERROR_NONE)
            goto exit;

        /* Verify signature */
        ret = yaca_memcmp(signature1, signature2, signature_len);
        if (ret != YACA_ERROR_NONE) {
            printf("Verification failed\n");
            goto exit;
        } else {
            printf("Verification successful\n");
        }
    }

exit:
    yaca_free(signature1);
    yaca_free(signature2);
    yaca_key_destroy(sym_key);
    yaca_context_destroy(ctx);

    yaca_cleanup();
    return ret;
}

Functions

int yaca_digest_initialize (yaca_context_h *ctx, yaca_digest_algorithm_e algo)
 Initializes a digest context.
int yaca_digest_update (yaca_context_h ctx, const char *message, size_t message_len)
 Feeds the message into the message digest algorithm.
int yaca_digest_finalize (yaca_context_h ctx, char *digest, size_t *digest_len)
 Calculates the final digest.
int yaca_sign_initialize (yaca_context_h *ctx, yaca_digest_algorithm_e algo, const yaca_key_h prv_key)
 Initializes a signature context for asymmetric signatures.
int yaca_sign_initialize_hmac (yaca_context_h *ctx, yaca_digest_algorithm_e algo, const yaca_key_h sym_key)
 Initializes a signature context for HMAC.
int yaca_sign_initialize_cmac (yaca_context_h *ctx, yaca_encrypt_algorithm_e algo, const yaca_key_h sym_key)
 Initializes a signature context for CMAC.
int yaca_sign_update (yaca_context_h ctx, const char *message, size_t message_len)
 Feeds the message into the digital signature or MAC algorithm.
int yaca_sign_finalize (yaca_context_h ctx, char *signature, size_t *signature_len)
 Calculates the final signature or MAC.
int yaca_verify_initialize (yaca_context_h *ctx, yaca_digest_algorithm_e algo, const yaca_key_h pub_key)
 Initializes a signature verification context for asymmetric signatures.
int yaca_verify_update (yaca_context_h ctx, const char *message, size_t message_len)
 Feeds the message into the digital signature verification algorithm.
int yaca_verify_finalize (yaca_context_h ctx, const char *signature, size_t signature_len)
 Performs the verification.

Function Documentation

int yaca_digest_finalize ( yaca_context_h  ctx,
char *  digest,
size_t *  digest_len 
)

Calculates the final digest.

Since :
3.0
Remarks:
Skipping yaca_digest_update() and calling only yaca_digest_finalize() will produce an empty message digest.
Parameters:
[in,out]ctxA valid digest context
[out]digestBuffer for the message digest (must be allocated by client, see yaca_context_get_output_length())
[out]digest_lenLength of the digest, actual number of bytes written will be returned here
Returns:
YACA_ERROR_NONE on success, negative on error
Return values:
YACA_ERROR_NONESuccessful
YACA_ERROR_INVALID_PARAMETERRequired parameters have incorrect values (NULL, invalid ctx)
YACA_ERROR_INTERNALInternal error
See also:
yaca_digest_initialize()
yaca_digest_update()
yaca_context_get_output_length()

Initializes a digest context.

Since :
3.0
Remarks:
The ctx should be released using yaca_context_destroy().
Parameters:
[out]ctxNewly created context
[in]algoDigest algorithm that will be used
Returns:
YACA_ERROR_NONE on success, negative on error
Return values:
YACA_ERROR_NONESuccessful
YACA_ERROR_INVALID_PARAMETERRequired parameters have incorrect values (NULL, invalid algo)
YACA_ERROR_OUT_OF_MEMORYOut of memory error
YACA_ERROR_INTERNALInternal error
See also:
yaca_digest_algorithm_e
yaca_digest_update()
yaca_digest_finalize()
yaca_context_destroy()
int yaca_digest_update ( yaca_context_h  ctx,
const char *  message,
size_t  message_len 
)

Feeds the message into the message digest algorithm.

Since :
3.0
Parameters:
[in,out]ctxContext created by yaca_digest_initialize()
[in]messageMessage from which the digest is to be calculated
[in]message_lenLength of the message
Returns:
YACA_ERROR_NONE on success, negative on error
Return values:
YACA_ERROR_NONESuccessful
YACA_ERROR_INVALID_PARAMETERRequired parameters have incorrect values (NULL, 0, invalid ctx)
YACA_ERROR_INTERNALInternal error
See also:
yaca_digest_initialize()
yaca_digest_finalize()
int yaca_sign_finalize ( yaca_context_h  ctx,
char *  signature,
size_t *  signature_len 
)

Calculates the final signature or MAC.

Since :
3.0
Remarks:
Skipping yaca_sign_update() and calling only yaca_sign_finalize() will produce a signature or MAC of an empty message.
Parameters:
[in,out]ctxA valid sign context
[out]signatureBuffer for the MAC or the message signature (must be allocated by client, see yaca_context_get_output_length())
[out]signature_lenLength of the MAC or the signature, actual number of bytes written will be returned here
Returns:
YACA_ERROR_NONE on success, negative on error
Return values:
YACA_ERROR_NONESuccessful
YACA_ERROR_INVALID_PARAMETERRequired parameters have incorrect values (NULL, invalid ctx)
YACA_ERROR_INTERNALInternal error
See also:
yaca_sign_initialize()
yaca_sign_update()
yaca_sign_initialize_hmac()
yaca_sign_initialize_cmac()
yaca_context_get_output_length()
int yaca_sign_initialize ( yaca_context_h ctx,
yaca_digest_algorithm_e  algo,
const yaca_key_h  prv_key 
)

Initializes a signature context for asymmetric signatures.

Since :
3.0
Remarks:
For verification use yaca_verify_initialize(), yaca_verify_update() and yaca_verify_finalize() functions with matching public key.
For RSA operations the default padding used is YACA_PADDING_PKCS1. It can be changed using yaca_context_set_property() with YACA_PROPERTY_PADDING.
For YACA_DIGEST_SHA384 and YACA_DIGEST_SHA512 the RSA key size must be bigger than YACA_KEY_LENGTH_512BIT.
Using of YACA_DIGEST_MD5 algorithm for DSA and ECDSA operations is prohibited.
Using of YACA_DIGEST_MD5 or YACA_DIGEST_SHA224 with YACA_PADDING_X931 is prohibited.
The ctx should be released using yaca_context_destroy().
Parameters:
[out]ctxNewly created context
[in]algoDigest algorithm that will be used
[in]prv_keyPrivate key that will be used, algorithm is deduced based on key type, supported key types:
Returns:
YACA_ERROR_NONE on success, negative on error
Return values:
YACA_ERROR_NONESuccessful
YACA_ERROR_INVALID_PARAMETERRequired parameters have incorrect values (NULL, invalid algo or prv_key)
YACA_ERROR_OUT_OF_MEMORYOut of memory error
YACA_ERROR_INTERNALInternal error
See also:
yaca_key_type_e
yaca_digest_algorithm_e
yaca_padding_e
yaca_context_set_property()
yaca_sign_update()
yaca_sign_finalize()
yaca_verify_initialize()
yaca_verify_update()
yaca_verify_finalize()
yaca_context_destroy()

Initializes a signature context for CMAC.

Since :
3.0
Remarks:
For verification, calculate message CMAC and compare with received MAC using yaca_memcmp().
The ctx should be released using yaca_context_destroy().
Parameters:
[out]ctxNewly created context
[in]algoEncryption algorithm that will be used
[in]sym_keySymmetric key that will be used, supported key types:
Returns:
YACA_ERROR_NONE on success, negative on error
Return values:
YACA_ERROR_NONESuccessful
YACA_ERROR_INVALID_PARAMETERRequired parameters have incorrect values (NULL, invalid algo or sym_key)
YACA_ERROR_OUT_OF_MEMORYOut of memory error
YACA_ERROR_INTERNALInternal error
See also:
yaca_key_type_e
yaca_encrypt_algorithm_e
yaca_sign_update()
yaca_sign_finalize()
yaca_memcmp()
yaca_context_destroy()
int yaca_sign_initialize_hmac ( yaca_context_h ctx,
yaca_digest_algorithm_e  algo,
const yaca_key_h  sym_key 
)

Initializes a signature context for HMAC.

Since :
3.0
Remarks:
For verification, calculate message HMAC and compare with received MAC using yaca_memcmp().
The ctx should be released using yaca_context_destroy().
Parameters:
[out]ctxNewly created context
[in]algoDigest algorithm that will be used
[in]sym_keySymmetric key that will be used, supported key types:
Returns:
YACA_ERROR_NONE on success, negative on error
Return values:
YACA_ERROR_NONESuccessful
YACA_ERROR_INVALID_PARAMETERRequired parameters have incorrect values (NULL, invalid algo or sym_key)
YACA_ERROR_OUT_OF_MEMORYOut of memory error
YACA_ERROR_INTERNALInternal error
See also:
yaca_key_type_e
yaca_digest_algorithm_e
yaca_sign_update()
yaca_sign_finalize()
yaca_memcmp()
yaca_context_destroy()
int yaca_sign_update ( yaca_context_h  ctx,
const char *  message,
size_t  message_len 
)

Feeds the message into the digital signature or MAC algorithm.

Since :
3.0
Parameters:
[in,out]ctxContext created by yaca_sign_initialize(), yaca_sign_initialize_hmac() or yaca_sign_initialize_cmac()
[in]messageMessage to be signed
[in]message_lenLength of the message
Returns:
YACA_ERROR_NONE on success, negative on error
Return values:
YACA_ERROR_NONESuccessful
YACA_ERROR_INVALID_PARAMETERRequired parameters have incorrect values (NULL, 0, invalid ctx)
YACA_ERROR_INTERNALInternal error
See also:
yaca_sign_initialize()
yaca_sign_finalize()
yaca_sign_initialize_hmac()
yaca_sign_initialize_cmac()
int yaca_verify_finalize ( yaca_context_h  ctx,
const char *  signature,
size_t  signature_len 
)

Performs the verification.

Since :
3.0
Remarks:
Skipping yaca_verify_update() and calling only yaca_verify_finalize() will verify the signature of an empty message.
Parameters:
[in,out]ctxA valid verify context
[in]signatureMessage signature to be verified
[in]signature_lenLength of the signature
Returns:
YACA_ERROR_NONE on success, negative on error
Return values:
YACA_ERROR_NONESuccessful
YACA_ERROR_INVALID_PARAMETERRequired parameters have incorrect values (NULL, invalid ctx)
YACA_ERROR_INTERNALInternal error
YACA_ERROR_DATA_MISMATCHThe verification failed
See also:
yaca_verify_initialize()
yaca_verify_update()
yaca_sign_finalize()
int yaca_verify_initialize ( yaca_context_h ctx,
yaca_digest_algorithm_e  algo,
const yaca_key_h  pub_key 
)

Initializes a signature verification context for asymmetric signatures.

Since :
3.0
Remarks:
For RSA operations the default padding used is YACA_PADDING_PKCS1. It can be changed using yaca_context_set_property() with YACA_PROPERTY_PADDING. For verify to succeed it has to be set to the same value it was signed with.
The ctx should be released using yaca_context_destroy().
Parameters:
[out]ctxNewly created context
[in]algoDigest algorithm that will be used
[in]pub_keyPublic key that will be used, algorithm is deduced based on key type, supported key types:
Returns:
YACA_ERROR_NONE on success, negative on error
Return values:
YACA_ERROR_NONESuccessful
YACA_ERROR_INVALID_PARAMETERRequired parameters have incorrect values (NULL, invalid algo or pub_key)
YACA_ERROR_OUT_OF_MEMORYOut of memory error
YACA_ERROR_INTERNALInternal error
See also:
yaca_key_type_e
yaca_digest_algorithm_e
yaca_padding_e
yaca_context_set_property()
yaca_verify_update()
yaca_verify_finalize()
yaca_context_destroy()
int yaca_verify_update ( yaca_context_h  ctx,
const char *  message,
size_t  message_len 
)

Feeds the message into the digital signature verification algorithm.

Since :
3.0
Parameters:
[in,out]ctxContext created by yaca_verify_initialize()
[in]messageMessage
[in]message_lenLength of the message
Returns:
YACA_ERROR_NONE on success, negative on error
Return values:
YACA_ERROR_NONESuccessful
YACA_ERROR_INVALID_PARAMETERRequired parameters have incorrect values (NULL, 0, invalid ctx)
YACA_ERROR_INTERNALInternal error
See also:
yaca_verify_initialize()
yaca_verify_finalize()