1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <openssl/core_dispatch.h> 11e1051a39Sopenharmony_ci#include <openssl/core_names.h> 12e1051a39Sopenharmony_ci#include <openssl/params.h> 13e1051a39Sopenharmony_ci#include <openssl/evp.h> 14e1051a39Sopenharmony_ci#include <openssl/err.h> 15e1051a39Sopenharmony_ci#include <openssl/proverr.h> 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ci#include "crypto/poly1305.h" 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ci#include "prov/implementations.h" 20e1051a39Sopenharmony_ci#include "prov/providercommon.h" 21e1051a39Sopenharmony_ci 22e1051a39Sopenharmony_ci/* 23e1051a39Sopenharmony_ci * Forward declaration of everything implemented here. This is not strictly 24e1051a39Sopenharmony_ci * necessary for the compiler, but provides an assurance that the signatures 25e1051a39Sopenharmony_ci * of the functions in the dispatch table are correct. 26e1051a39Sopenharmony_ci */ 27e1051a39Sopenharmony_cistatic OSSL_FUNC_mac_newctx_fn poly1305_new; 28e1051a39Sopenharmony_cistatic OSSL_FUNC_mac_dupctx_fn poly1305_dup; 29e1051a39Sopenharmony_cistatic OSSL_FUNC_mac_freectx_fn poly1305_free; 30e1051a39Sopenharmony_cistatic OSSL_FUNC_mac_gettable_params_fn poly1305_gettable_params; 31e1051a39Sopenharmony_cistatic OSSL_FUNC_mac_get_params_fn poly1305_get_params; 32e1051a39Sopenharmony_cistatic OSSL_FUNC_mac_settable_ctx_params_fn poly1305_settable_ctx_params; 33e1051a39Sopenharmony_cistatic OSSL_FUNC_mac_set_ctx_params_fn poly1305_set_ctx_params; 34e1051a39Sopenharmony_cistatic OSSL_FUNC_mac_init_fn poly1305_init; 35e1051a39Sopenharmony_cistatic OSSL_FUNC_mac_update_fn poly1305_update; 36e1051a39Sopenharmony_cistatic OSSL_FUNC_mac_final_fn poly1305_final; 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_cistruct poly1305_data_st { 39e1051a39Sopenharmony_ci void *provctx; 40e1051a39Sopenharmony_ci int updated; 41e1051a39Sopenharmony_ci POLY1305 poly1305; /* Poly1305 data */ 42e1051a39Sopenharmony_ci}; 43e1051a39Sopenharmony_ci 44e1051a39Sopenharmony_cistatic void *poly1305_new(void *provctx) 45e1051a39Sopenharmony_ci{ 46e1051a39Sopenharmony_ci struct poly1305_data_st *ctx; 47e1051a39Sopenharmony_ci 48e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 49e1051a39Sopenharmony_ci return NULL; 50e1051a39Sopenharmony_ci ctx = OPENSSL_zalloc(sizeof(*ctx)); 51e1051a39Sopenharmony_ci if (ctx != NULL) 52e1051a39Sopenharmony_ci ctx->provctx = provctx; 53e1051a39Sopenharmony_ci return ctx; 54e1051a39Sopenharmony_ci} 55e1051a39Sopenharmony_ci 56e1051a39Sopenharmony_cistatic void poly1305_free(void *vmacctx) 57e1051a39Sopenharmony_ci{ 58e1051a39Sopenharmony_ci OPENSSL_free(vmacctx); 59e1051a39Sopenharmony_ci} 60e1051a39Sopenharmony_ci 61e1051a39Sopenharmony_cistatic void *poly1305_dup(void *vsrc) 62e1051a39Sopenharmony_ci{ 63e1051a39Sopenharmony_ci struct poly1305_data_st *src = vsrc; 64e1051a39Sopenharmony_ci struct poly1305_data_st *dst; 65e1051a39Sopenharmony_ci 66e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 67e1051a39Sopenharmony_ci return NULL; 68e1051a39Sopenharmony_ci dst = OPENSSL_malloc(sizeof(*dst)); 69e1051a39Sopenharmony_ci if (dst == NULL) 70e1051a39Sopenharmony_ci return NULL; 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci *dst = *src; 73e1051a39Sopenharmony_ci return dst; 74e1051a39Sopenharmony_ci} 75e1051a39Sopenharmony_ci 76e1051a39Sopenharmony_cistatic size_t poly1305_size(void) 77e1051a39Sopenharmony_ci{ 78e1051a39Sopenharmony_ci return POLY1305_DIGEST_SIZE; 79e1051a39Sopenharmony_ci} 80e1051a39Sopenharmony_ci 81e1051a39Sopenharmony_cistatic int poly1305_setkey(struct poly1305_data_st *ctx, 82e1051a39Sopenharmony_ci const unsigned char *key, size_t keylen) 83e1051a39Sopenharmony_ci{ 84e1051a39Sopenharmony_ci if (keylen != POLY1305_KEY_SIZE) { 85e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); 86e1051a39Sopenharmony_ci return 0; 87e1051a39Sopenharmony_ci } 88e1051a39Sopenharmony_ci Poly1305_Init(&ctx->poly1305, key); 89e1051a39Sopenharmony_ci ctx->updated = 0; 90e1051a39Sopenharmony_ci return 1; 91e1051a39Sopenharmony_ci} 92e1051a39Sopenharmony_ci 93e1051a39Sopenharmony_cistatic int poly1305_init(void *vmacctx, const unsigned char *key, 94e1051a39Sopenharmony_ci size_t keylen, const OSSL_PARAM params[]) 95e1051a39Sopenharmony_ci{ 96e1051a39Sopenharmony_ci struct poly1305_data_st *ctx = vmacctx; 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ci /* initialize the context in MAC_ctrl function */ 99e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || !poly1305_set_ctx_params(ctx, params)) 100e1051a39Sopenharmony_ci return 0; 101e1051a39Sopenharmony_ci if (key != NULL) 102e1051a39Sopenharmony_ci return poly1305_setkey(ctx, key, keylen); 103e1051a39Sopenharmony_ci /* no reinitialization of context with the same key is allowed */ 104e1051a39Sopenharmony_ci return ctx->updated == 0; 105e1051a39Sopenharmony_ci} 106e1051a39Sopenharmony_ci 107e1051a39Sopenharmony_cistatic int poly1305_update(void *vmacctx, const unsigned char *data, 108e1051a39Sopenharmony_ci size_t datalen) 109e1051a39Sopenharmony_ci{ 110e1051a39Sopenharmony_ci struct poly1305_data_st *ctx = vmacctx; 111e1051a39Sopenharmony_ci 112e1051a39Sopenharmony_ci ctx->updated = 1; 113e1051a39Sopenharmony_ci if (datalen == 0) 114e1051a39Sopenharmony_ci return 1; 115e1051a39Sopenharmony_ci 116e1051a39Sopenharmony_ci /* poly1305 has nothing to return in its update function */ 117e1051a39Sopenharmony_ci Poly1305_Update(&ctx->poly1305, data, datalen); 118e1051a39Sopenharmony_ci return 1; 119e1051a39Sopenharmony_ci} 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_cistatic int poly1305_final(void *vmacctx, unsigned char *out, size_t *outl, 122e1051a39Sopenharmony_ci size_t outsize) 123e1051a39Sopenharmony_ci{ 124e1051a39Sopenharmony_ci struct poly1305_data_st *ctx = vmacctx; 125e1051a39Sopenharmony_ci 126e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 127e1051a39Sopenharmony_ci return 0; 128e1051a39Sopenharmony_ci ctx->updated = 1; 129e1051a39Sopenharmony_ci Poly1305_Final(&ctx->poly1305, out); 130e1051a39Sopenharmony_ci *outl = poly1305_size(); 131e1051a39Sopenharmony_ci return 1; 132e1051a39Sopenharmony_ci} 133e1051a39Sopenharmony_ci 134e1051a39Sopenharmony_cistatic const OSSL_PARAM known_gettable_params[] = { 135e1051a39Sopenharmony_ci OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), 136e1051a39Sopenharmony_ci OSSL_PARAM_END 137e1051a39Sopenharmony_ci}; 138e1051a39Sopenharmony_cistatic const OSSL_PARAM *poly1305_gettable_params(void *provctx) 139e1051a39Sopenharmony_ci{ 140e1051a39Sopenharmony_ci return known_gettable_params; 141e1051a39Sopenharmony_ci} 142e1051a39Sopenharmony_ci 143e1051a39Sopenharmony_cistatic int poly1305_get_params(OSSL_PARAM params[]) 144e1051a39Sopenharmony_ci{ 145e1051a39Sopenharmony_ci OSSL_PARAM *p; 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL) 148e1051a39Sopenharmony_ci return OSSL_PARAM_set_size_t(p, poly1305_size()); 149e1051a39Sopenharmony_ci 150e1051a39Sopenharmony_ci return 1; 151e1051a39Sopenharmony_ci} 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_cistatic const OSSL_PARAM known_settable_ctx_params[] = { 154e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0), 155e1051a39Sopenharmony_ci OSSL_PARAM_END 156e1051a39Sopenharmony_ci}; 157e1051a39Sopenharmony_cistatic const OSSL_PARAM *poly1305_settable_ctx_params(ossl_unused void *ctx, 158e1051a39Sopenharmony_ci ossl_unused void *provctx) 159e1051a39Sopenharmony_ci{ 160e1051a39Sopenharmony_ci return known_settable_ctx_params; 161e1051a39Sopenharmony_ci} 162e1051a39Sopenharmony_ci 163e1051a39Sopenharmony_cistatic int poly1305_set_ctx_params(void *vmacctx, const OSSL_PARAM *params) 164e1051a39Sopenharmony_ci{ 165e1051a39Sopenharmony_ci struct poly1305_data_st *ctx = vmacctx; 166e1051a39Sopenharmony_ci const OSSL_PARAM *p; 167e1051a39Sopenharmony_ci 168e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL 169e1051a39Sopenharmony_ci && !poly1305_setkey(ctx, p->data, p->data_size)) 170e1051a39Sopenharmony_ci return 0; 171e1051a39Sopenharmony_ci return 1; 172e1051a39Sopenharmony_ci} 173e1051a39Sopenharmony_ci 174e1051a39Sopenharmony_ciconst OSSL_DISPATCH ossl_poly1305_functions[] = { 175e1051a39Sopenharmony_ci { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))poly1305_new }, 176e1051a39Sopenharmony_ci { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))poly1305_dup }, 177e1051a39Sopenharmony_ci { OSSL_FUNC_MAC_FREECTX, (void (*)(void))poly1305_free }, 178e1051a39Sopenharmony_ci { OSSL_FUNC_MAC_INIT, (void (*)(void))poly1305_init }, 179e1051a39Sopenharmony_ci { OSSL_FUNC_MAC_UPDATE, (void (*)(void))poly1305_update }, 180e1051a39Sopenharmony_ci { OSSL_FUNC_MAC_FINAL, (void (*)(void))poly1305_final }, 181e1051a39Sopenharmony_ci { OSSL_FUNC_MAC_GETTABLE_PARAMS, (void (*)(void))poly1305_gettable_params }, 182e1051a39Sopenharmony_ci { OSSL_FUNC_MAC_GET_PARAMS, (void (*)(void))poly1305_get_params }, 183e1051a39Sopenharmony_ci { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, 184e1051a39Sopenharmony_ci (void (*)(void))poly1305_settable_ctx_params }, 185e1051a39Sopenharmony_ci { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))poly1305_set_ctx_params }, 186e1051a39Sopenharmony_ci { 0, NULL } 187e1051a39Sopenharmony_ci}; 188