qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

hmac.c (3082B)


      1 /*
      2  * QEMU Crypto hmac algorithms
      3  *
      4  * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
      5  *
      6  * This work is licensed under the terms of the GNU GPL, version 2 or
      7  * (at your option) any later version.  See the COPYING file in the
      8  * top-level directory.
      9  *
     10  */
     11 
     12 #include "qemu/osdep.h"
     13 #include "crypto/hmac.h"
     14 #include "hmacpriv.h"
     15 
     16 static const char hex[] = "0123456789abcdef";
     17 
     18 int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
     19                         const struct iovec *iov,
     20                         size_t niov,
     21                         uint8_t **result,
     22                         size_t *resultlen,
     23                         Error **errp)
     24 {
     25     QCryptoHmacDriver *drv = hmac->driver;
     26 
     27     return drv->hmac_bytesv(hmac, iov, niov, result, resultlen, errp);
     28 }
     29 
     30 int qcrypto_hmac_bytes(QCryptoHmac *hmac,
     31                        const char *buf,
     32                        size_t len,
     33                        uint8_t **result,
     34                        size_t *resultlen,
     35                        Error **errp)
     36 {
     37     struct iovec iov = {
     38             .iov_base = (char *)buf,
     39             .iov_len = len
     40     };
     41 
     42     return qcrypto_hmac_bytesv(hmac, &iov, 1, result, resultlen, errp);
     43 }
     44 
     45 int qcrypto_hmac_digestv(QCryptoHmac *hmac,
     46                          const struct iovec *iov,
     47                          size_t niov,
     48                          char **digest,
     49                          Error **errp)
     50 {
     51     uint8_t *result = NULL;
     52     size_t resultlen = 0;
     53     size_t i;
     54 
     55     if (qcrypto_hmac_bytesv(hmac, iov, niov, &result, &resultlen, errp) < 0) {
     56         return -1;
     57     }
     58 
     59     *digest = g_new0(char, (resultlen * 2) + 1);
     60 
     61     for (i = 0 ; i < resultlen ; i++) {
     62         (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf];
     63         (*digest)[(i * 2) + 1] = hex[result[i] & 0xf];
     64     }
     65 
     66     (*digest)[resultlen * 2] = '\0';
     67 
     68     g_free(result);
     69     return 0;
     70 }
     71 
     72 int qcrypto_hmac_digest(QCryptoHmac *hmac,
     73                         const char *buf,
     74                         size_t len,
     75                         char **digest,
     76                         Error **errp)
     77 {
     78     struct iovec iov = {
     79             .iov_base = (char *)buf,
     80             .iov_len = len
     81     };
     82 
     83     return qcrypto_hmac_digestv(hmac, &iov, 1, digest, errp);
     84 }
     85 
     86 QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
     87                               const uint8_t *key, size_t nkey,
     88                               Error **errp)
     89 {
     90     QCryptoHmac *hmac;
     91     void *ctx = NULL;
     92     QCryptoHmacDriver *drv = NULL;
     93 
     94 #ifdef CONFIG_AF_ALG
     95     ctx = qcrypto_afalg_hmac_ctx_new(alg, key, nkey, NULL);
     96     if (ctx) {
     97         drv = &qcrypto_hmac_afalg_driver;
     98     }
     99 #endif
    100 
    101     if (!ctx) {
    102         ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp);
    103         if (!ctx) {
    104             return NULL;
    105         }
    106 
    107         drv = &qcrypto_hmac_lib_driver;
    108     }
    109 
    110     hmac = g_new0(QCryptoHmac, 1);
    111     hmac->alg = alg;
    112     hmac->opaque = ctx;
    113     hmac->driver = (void *)drv;
    114 
    115     return hmac;
    116 }
    117 
    118 void qcrypto_hmac_free(QCryptoHmac *hmac)
    119 {
    120     QCryptoHmacDriver *drv;
    121 
    122     if (hmac) {
    123         drv = hmac->driver;
    124         drv->hmac_free(hmac);
    125         g_free(hmac);
    126     }
    127 }