qemu

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

afalg.c (2781B)


      1 /*
      2  * QEMU Crypto af_alg support
      3  *
      4  * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD.
      5  *
      6  * Authors:
      7  *    Longpeng(Mike) <longpeng2@huawei.com>
      8  *
      9  * This work is licensed under the terms of the GNU GPL, version 2 or
     10  * (at your option) any later version.  See the COPYING file in the
     11  * top-level directory.
     12  */
     13 #include "qemu/osdep.h"
     14 #include "qemu/cutils.h"
     15 #include "qemu/sockets.h"
     16 #include "qapi/error.h"
     17 #include "afalgpriv.h"
     18 
     19 static bool
     20 qcrypto_afalg_build_saddr(const char *type, const char *name,
     21                           struct sockaddr_alg *salg, Error **errp)
     22 {
     23     salg->salg_family = AF_ALG;
     24 
     25     if (strnlen(type, SALG_TYPE_LEN_MAX) >= SALG_TYPE_LEN_MAX) {
     26         error_setg(errp, "Afalg type(%s) is larger than %d bytes",
     27                    type, SALG_TYPE_LEN_MAX);
     28         return false;
     29     }
     30 
     31     if (strnlen(name, SALG_NAME_LEN_MAX) >= SALG_NAME_LEN_MAX) {
     32         error_setg(errp, "Afalg name(%s) is larger than %d bytes",
     33                    name, SALG_NAME_LEN_MAX);
     34         return false;
     35     }
     36 
     37     pstrcpy((char *)salg->salg_type, SALG_TYPE_LEN_MAX, type);
     38     pstrcpy((char *)salg->salg_name, SALG_NAME_LEN_MAX, name);
     39 
     40     return true;
     41 }
     42 
     43 static int
     44 qcrypto_afalg_socket_bind(const char *type, const char *name,
     45                           Error **errp)
     46 {
     47     int sbind;
     48     struct sockaddr_alg salg = {0};
     49 
     50     if (!qcrypto_afalg_build_saddr(type, name, &salg, errp)) {
     51         return -1;
     52     }
     53 
     54     sbind = qemu_socket(AF_ALG, SOCK_SEQPACKET, 0);
     55     if (sbind < 0) {
     56         error_setg_errno(errp, errno, "Failed to create socket");
     57         return -1;
     58     }
     59 
     60     if (bind(sbind, (const struct sockaddr *)&salg, sizeof(salg)) != 0) {
     61         error_setg_errno(errp, errno, "Failed to bind socket");
     62         closesocket(sbind);
     63         return -1;
     64     }
     65 
     66     return sbind;
     67 }
     68 
     69 QCryptoAFAlg *
     70 qcrypto_afalg_comm_alloc(const char *type, const char *name,
     71                          Error **errp)
     72 {
     73     QCryptoAFAlg *afalg;
     74 
     75     afalg = g_new0(QCryptoAFAlg, 1);
     76     /* initilize crypto API socket */
     77     afalg->opfd = -1;
     78     afalg->tfmfd = qcrypto_afalg_socket_bind(type, name, errp);
     79     if (afalg->tfmfd == -1) {
     80         goto error;
     81     }
     82 
     83     afalg->opfd = qemu_accept(afalg->tfmfd, NULL, 0);
     84     if (afalg->opfd == -1) {
     85         error_setg_errno(errp, errno, "Failed to accept socket");
     86         goto error;
     87     }
     88 
     89     return afalg;
     90 
     91 error:
     92     qcrypto_afalg_comm_free(afalg);
     93     return NULL;
     94 }
     95 
     96 void qcrypto_afalg_comm_free(QCryptoAFAlg *afalg)
     97 {
     98     if (!afalg) {
     99         return;
    100     }
    101 
    102     if (afalg->msg) {
    103         g_free(afalg->msg->msg_control);
    104         g_free(afalg->msg);
    105     }
    106 
    107     if (afalg->tfmfd != -1) {
    108         closesocket(afalg->tfmfd);
    109     }
    110 
    111     if (afalg->opfd != -1) {
    112         closesocket(afalg->opfd);
    113     }
    114 
    115     g_free(afalg);
    116 }