diff mbox

[v4,12/18] crypto: introduce some common functions for af_alg backend

Message ID 1499158630-75260-13-git-send-email-longpeng2@huawei.com (mailing list archive)
State New, archived
Headers show

Commit Message

Longpeng(Mike) July 4, 2017, 8:57 a.m. UTC
The AF_ALG socket family is the userspace interface for linux
crypto API, this patch adds af_alg family support and some common
functions for af_alg backend. It'll be used by afalg-backend crypto
latter.

Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 configure            |  22 ++++++++++
 crypto/Makefile.objs |   1 +
 crypto/afalg.c       | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++
 crypto/afalgpriv.h   |  55 ++++++++++++++++++++++++
 4 files changed, 196 insertions(+)
 create mode 100644 crypto/afalg.c
 create mode 100644 crypto/afalgpriv.h

Comments

Daniel P. Berrangé July 11, 2017, 12:28 p.m. UTC | #1
On Tue, Jul 04, 2017 at 04:57:04PM +0800, Longpeng(Mike) wrote:
> The AF_ALG socket family is the userspace interface for linux
> crypto API, this patch adds af_alg family support and some common
> functions for af_alg backend. It'll be used by afalg-backend crypto
> latter.
> 
> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> ---
>  configure            |  22 ++++++++++
>  crypto/Makefile.objs |   1 +
>  crypto/afalg.c       | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  crypto/afalgpriv.h   |  55 ++++++++++++++++++++++++
>  4 files changed, 196 insertions(+)
>  create mode 100644 crypto/afalg.c
>  create mode 100644 crypto/afalgpriv.h
> 
> diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
> new file mode 100644
> index 0000000..d21160c
> --- /dev/null
> +++ b/crypto/afalgpriv.h
> @@ -0,0 +1,55 @@

> +
> +struct QCryptoAFAlg {
> +    int tfmfd;
> +    int opfd;
> +    char *name;

What actually uses this 'name' field ?  I'm not seing anything in the
patch series that ever reads it, once set. So can we just delete it
perhaps ?

> +    struct msghdr *msg;
> +    struct cmsghdr *cmsg;
> +};

Regards,
Daniel
long mike July 13, 2017, 3:30 a.m. UTC | #2
2017-07-11 20:28 GMT+08:00 Daniel P. Berrange <berrange@redhat.com>:
> On Tue, Jul 04, 2017 at 04:57:04PM +0800, Longpeng(Mike) wrote:
>> The AF_ALG socket family is the userspace interface for linux
>> crypto API, this patch adds af_alg family support and some common
>> functions for af_alg backend. It'll be used by afalg-backend crypto
>> latter.
>>
>> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
>> ---
>>  configure            |  22 ++++++++++
>>  crypto/Makefile.objs |   1 +
>>  crypto/afalg.c       | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>  crypto/afalgpriv.h   |  55 ++++++++++++++++++++++++
>>  4 files changed, 196 insertions(+)
>>  create mode 100644 crypto/afalg.c
>>  create mode 100644 crypto/afalgpriv.h
>>
>> diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
>> new file mode 100644
>> index 0000000..d21160c
>> --- /dev/null
>> +++ b/crypto/afalgpriv.h
>> @@ -0,0 +1,55 @@
>
>> +
>> +struct QCryptoAFAlg {
>> +    int tfmfd;
>> +    int opfd;
>> +    char *name;
>
> What actually uses this 'name' field ?  I'm not seing anything in the
> patch series that ever reads it, once set. So can we just delete it
> perhaps ?
>
Hi Daniel,

I'm on vacation so I can just replay messages through my personal
email account these days.

Yes, the 'name' field isn't used by others, it just for debug, it's
convenient.  But if you don't like it, I'll remove it.

PS: I'll have a close look at your other suggestions and send v5 as
soon as possible. Thanks :)

Reards,
Longpeng

>> +    struct msghdr *msg;
>> +    struct cmsghdr *cmsg;
>> +};
>
> Regards,
> Daniel
> --
> |: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-            https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
diff mbox

Patch

diff --git a/configure b/configure
index c571ad1..0b3e6c1 100755
--- a/configure
+++ b/configure
@@ -4744,6 +4744,24 @@  if compile_prog "" "" ; then
     have_af_vsock=yes
 fi
 
+##########################################
+# check for usable AF_ALG environment
+hava_af_alg=no
+cat > $TMPC << EOF
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/if_alg.h>
+int main(void) {
+    int sock;
+    sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
+    return sock;
+}
+EOF
+if compile_prog "" "" ; then
+    have_af_alg=yes
+fi
+
 #################################################
 # Sparc implicitly links with --relax, which is
 # incompatible with -r, so --no-relax should be
@@ -5855,6 +5873,10 @@  if test "$have_af_vsock" = "yes" ; then
   echo "CONFIG_AF_VSOCK=y" >> $config_host_mak
 fi
 
+if test "$have_af_alg" = "yes" ; then
+  echo "CONFIG_AF_ALG=y" >> $config_host_mak
+fi
+
 if test "$have_sysmacros" = "yes" ; then
   echo "CONFIG_SYSMACROS=y" >> $config_host_mak
 fi
diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index 1f749f2..2be5a3a 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -10,6 +10,7 @@  crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT_HMAC),n,y)) += hmac-glib
 crypto-obj-y += aes.o
 crypto-obj-y += desrfb.o
 crypto-obj-y += cipher.o
+crypto-obj-$(CONFIG_AF_ALG) += afalg.o
 crypto-obj-y += tlscreds.o
 crypto-obj-y += tlscredsanon.o
 crypto-obj-y += tlscredsx509.o
diff --git a/crypto/afalg.c b/crypto/afalg.c
new file mode 100644
index 0000000..337d8a8
--- /dev/null
+++ b/crypto/afalg.c
@@ -0,0 +1,118 @@ 
+/*
+ * QEMU Crypto af_alg support
+ *
+ * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *    Longpeng(Mike) <longpeng2@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version.  See the COPYING file in the
+ * top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "qemu/sockets.h"
+#include "qapi/error.h"
+#include "afalgpriv.h"
+
+static bool
+qcrypto_afalg_build_saddr(const char *type, const char *name,
+                          struct sockaddr_alg *salg, Error **errp)
+{
+    salg->salg_family = AF_ALG;
+
+    if (strnlen(type, SALG_TYPE_LEN_MAX) >= SALG_TYPE_LEN_MAX) {
+        error_setg(errp, "Afalg type(%s) is larger than %d bytes",
+                   type, SALG_TYPE_LEN_MAX);
+        return false;
+    }
+
+    if (strnlen(name, SALG_NAME_LEN_MAX) >= SALG_NAME_LEN_MAX) {
+        error_setg(errp, "Afalg name(%s) is larger than %d bytes",
+                   name, SALG_NAME_LEN_MAX);
+        return false;
+    }
+
+    pstrcpy((char *)salg->salg_type, SALG_TYPE_LEN_MAX, type);
+    pstrcpy((char *)salg->salg_name, SALG_NAME_LEN_MAX, name);
+
+    return true;
+}
+
+static int
+qcrypto_afalg_socket_bind(const char *type, const char *name,
+                          Error **errp)
+{
+    int sbind;
+    struct sockaddr_alg salg = {0};
+
+    if (!qcrypto_afalg_build_saddr(type, name, &salg, errp)) {
+        return -1;
+    }
+
+    sbind = qemu_socket(AF_ALG, SOCK_SEQPACKET, 0);
+    if (sbind < 0) {
+        error_setg_errno(errp, errno, "Failed to create socket");
+        return -1;
+    }
+
+    if (bind(sbind, (const struct sockaddr *)&salg, sizeof(salg)) != 0) {
+        error_setg_errno(errp, errno, "Failed to bind socket");
+        closesocket(sbind);
+        return -1;
+    }
+
+    return sbind;
+}
+
+QCryptoAFAlg *
+qcrypto_afalg_comm_alloc(const char *type, const char *name,
+                         Error **errp)
+{
+    QCryptoAFAlg *afalg;
+
+    afalg = g_new0(QCryptoAFAlg, 1);
+    /* initilize crypto API socket */
+    afalg->opfd = -1;
+    afalg->tfmfd = qcrypto_afalg_socket_bind(type, name, errp);
+    if (afalg->tfmfd == -1) {
+        goto error;
+    }
+
+    afalg->opfd = qemu_accept(afalg->tfmfd, NULL, 0);
+    if (afalg->opfd == -1) {
+        error_setg_errno(errp, errno, "Failed to accept socket");
+        goto error;
+    }
+
+    return afalg;
+
+error:
+    qcrypto_afalg_comm_free(afalg);
+    return NULL;
+}
+
+void qcrypto_afalg_comm_free(QCryptoAFAlg *afalg)
+{
+    if (!afalg) {
+        return;
+    }
+
+    if (afalg->msg) {
+        g_free(afalg->msg->msg_control);
+        g_free(afalg->msg);
+    }
+
+    g_free(afalg->name);
+
+    if (afalg->tfmfd != -1) {
+        closesocket(afalg->tfmfd);
+    }
+
+    if (afalg->opfd != -1) {
+        closesocket(afalg->opfd);
+    }
+
+    g_free(afalg);
+}
diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
new file mode 100644
index 0000000..d21160c
--- /dev/null
+++ b/crypto/afalgpriv.h
@@ -0,0 +1,55 @@ 
+/*
+ * QEMU Crypto af_alg support
+ *
+ * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *    Longpeng(Mike) <longpeng2@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version.  See the COPYING file in the
+ * top-level directory.
+ */
+
+#ifndef QCRYPTO_AFALGPRIV_H
+#define QCRYPTO_AFALGPRIV_H
+
+#include <linux/if_alg.h>
+
+#define SALG_TYPE_LEN_MAX 14
+#define SALG_NAME_LEN_MAX 64
+
+typedef struct QCryptoAFAlg QCryptoAFAlg;
+
+struct QCryptoAFAlg {
+    int tfmfd;
+    int opfd;
+    char *name;
+    struct msghdr *msg;
+    struct cmsghdr *cmsg;
+};
+
+/**
+ * qcrypto_afalg_comm_alloc:
+ * @type: the type of crypto operation
+ * @name: the name of crypto operation
+ *
+ * Allocate a QCryptoAFAlg object and bind itself to
+ * a AF_ALG socket.
+ *
+ * Returns:
+ *  a new QCryptoAFAlg object, or NULL in error.
+ */
+QCryptoAFAlg *
+qcrypto_afalg_comm_alloc(const char *type, const char *name,
+                         Error **errp);
+
+/**
+ * afalg_comm_free:
+ * @afalg: the QCryptoAFAlg object
+ *
+ * Free the @afalg.
+ */
+void qcrypto_afalg_comm_free(QCryptoAFAlg *afalg);
+
+#endif