Systemd: backport a new api for uuid generation

The current uuid generation method just export the machine-id,
it does not match the systemd description
(https://www.freedesktop.org/software/systemd/man/machine-id.html):
This ID uniquely identifies the host. It should be considered
"confidential", and must not be exposed in untrusted environments,
in particular on the network. If a stable unique identifier that is
tied to the machine is needed for some application, the machine ID
or any part of it must not be used directly.

Backport the new sd_id128_get_machine_app_specific from systemd 233,
to replace the old uuid generation method.

Change-Id: I44e7b32ca951a9fa591761c3a3e4f27da04d2b6f
Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
diff --git a/common/recipes-core/systemd/systemd/0008-man-update-machine-id-5-with-a-note-about-privacy-46.patch b/common/recipes-core/systemd/systemd/0008-man-update-machine-id-5-with-a-note-about-privacy-46.patch
new file mode 100644
index 0000000..7d793bf
--- /dev/null
+++ b/common/recipes-core/systemd/systemd/0008-man-update-machine-id-5-with-a-note-about-privacy-46.patch
@@ -0,0 +1,62 @@
+From d48bb46b5a8a3a718948789a776d238c065fff88 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Fri, 11 Nov 2016 07:31:52 -0500
+Subject: [PATCH] man: update machine-id(5) with a note about privacy (#4645)
+
+---
+ man/machine-id.xml | 29 +++++++++++++++--------------
+ 1 file changed, 15 insertions(+), 14 deletions(-)
+
+diff --git a/man/machine-id.xml b/man/machine-id.xml
+index d318ec5..a722649 100644
+--- a/man/machine-id.xml
++++ b/man/machine-id.xml
+@@ -53,30 +53,31 @@
+   <refsect1>
+     <title>Description</title>
+ 
+-    <para>The <filename>/etc/machine-id</filename> file contains the
+-    unique machine ID of the local system that is set during
+-    installation. The machine ID is a single newline-terminated,
+-    hexadecimal, 32-character, lowercase machine ID string. When
+-    decoded from hexadecimal, this corresponds with a 16-byte/128-bit
+-    string.</para>
++    <para>The <filename>/etc/machine-id</filename> file contains the unique machine ID of the local
++    system that is set during installation. The machine ID is a single newline-terminated,
++    hexadecimal, 32-character, lowercase ID. When decoded from hexadecimal, this corresponds to a
++    16-byte/128-bit value.</para>
+ 
+     <para>The machine ID is usually generated from a random source
+     during system installation and stays constant for all subsequent
+     boots. Optionally, for stateless systems, it is generated during
+     runtime at early boot if it is found to be empty.</para>
+ 
+-    <para>The machine ID does not change based on user configuration
+-    or when hardware is replaced.</para>
++    <para>The machine ID does not change based on local or network configuration or when hardware is
++    replaced. Due to this and its greater length, it is a more useful replacement for the
++    <citerefentry project='man-pages'><refentrytitle>gethostid</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++    call that POSIX specifies.</para>
+ 
+     <para>This machine ID adheres to the same format and logic as the
+     D-Bus machine ID.</para>
+ 
+-    <para>Programs may use this ID to identify the host with a
+-    globally unique ID in the network, which does not change even if
+-    the local network configuration changes. Due to this and its
+-    greater length, it is a more useful replacement for the
+-    <citerefentry project='man-pages'><refentrytitle>gethostid</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+-    call that POSIX specifies.</para>
++    <para>This ID uniquely identifies the host. It should be considered "confidential", and must not
++    be exposed in untrusted environments, in particular on the network. If a stable unique
++    identifier that is tied to the machine is needed for some application, the machine ID or any
++    part of it must not be used directly. Instead the machine ID should be hashed with a
++    cryptographic, keyed hash function, using a fixed, application-specific key. That way the ID
++    will be properly unique, and derived in a constant way from the machine ID but there will be no
++    way to retrieve the original machine ID from the application-specific one.</para>
+ 
+     <para>The
+     <citerefentry><refentrytitle>systemd-machine-id-setup</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+-- 
+2.7.4
+
diff --git a/common/recipes-core/systemd/systemd/0009-sd-id128-add-new-sd_id128_get_machine_app_specific-A.patch b/common/recipes-core/systemd/systemd/0009-sd-id128-add-new-sd_id128_get_machine_app_specific-A.patch
new file mode 100644
index 0000000..64323bf
--- /dev/null
+++ b/common/recipes-core/systemd/systemd/0009-sd-id128-add-new-sd_id128_get_machine_app_specific-A.patch
@@ -0,0 +1,285 @@
+From 70fc4f57902290c48bec9acb2393ded84c09d4ca Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 17 Nov 2016 17:07:46 +0100
+Subject: [PATCH] sd-id128: add new sd_id128_get_machine_app_specific() API
+
+This adds an API for retrieving an app-specific machine ID to sd-id128.
+Internally it calculates HMAC-SHA256 with an 128bit app-specific ID as payload
+and the machine ID as key.
+
+(An alternative would have been to use siphash for this, which is also
+cryptographically strong. However, as it only generates 64bit hashes it's not
+an obvious choice for generating 128bit IDs.)
+
+Fixes: #4667
+---
+ Makefile-man.am                    |  5 +++
+ man/machine-id.xml                 | 15 +++++----
+ man/sd_id128_get_machine.xml       | 65 +++++++++++++++++++++++++++++++-------
+ src/libsystemd/libsystemd.sym      |  5 +++
+ src/libsystemd/sd-id128/sd-id128.c | 32 +++++++++++++++++++
+ src/systemd/sd-id128.h             |  2 +-
+ src/test/test-id128.c              |  6 ++++
+ 7 files changed, 110 insertions(+), 20 deletions(-)
+
+diff --git a/Makefile-man.am b/Makefile-man.am
+index 013e0d7..228e29f 100644
+--- a/Makefile-man.am
++++ b/Makefile-man.am
+@@ -397,6 +397,7 @@ MANPAGES_ALIAS += \
+ 	man/sd_id128_from_string.3 \
+ 	man/sd_id128_get_boot.3 \
+ 	man/sd_id128_get_invocation.3 \
++	man/sd_id128_get_machine_app_specific.3 \
+ 	man/sd_id128_is_null.3 \
+ 	man/sd_id128_t.3 \
+ 	man/sd_is_mq.3 \
+@@ -750,6 +751,7 @@ man/sd_id128_equal.3: man/sd-id128.3
+ man/sd_id128_from_string.3: man/sd_id128_to_string.3
+ man/sd_id128_get_boot.3: man/sd_id128_get_machine.3
+ man/sd_id128_get_invocation.3: man/sd_id128_get_machine.3
++man/sd_id128_get_machine_app_specific.3: man/sd_id128_get_machine.3
+ man/sd_id128_is_null.3: man/sd-id128.3
+ man/sd_id128_t.3: man/sd-id128.3
+ man/sd_is_mq.3: man/sd_is_fifo.3
+@@ -1531,6 +1533,9 @@ man/sd_id128_get_boot.html: man/sd_id128_get_machine.html
+ man/sd_id128_get_invocation.html: man/sd_id128_get_machine.html
+ 	$(html-alias)
+ 
++man/sd_id128_get_machine_app_specific.html: man/sd_id128_get_machine.html
++	$(html-alias)
++
+ man/sd_id128_is_null.html: man/sd-id128.html
+ 	$(html-alias)
+ 
+diff --git a/man/machine-id.xml b/man/machine-id.xml
+index a722649..3c261bf 100644
+--- a/man/machine-id.xml
++++ b/man/machine-id.xml
+@@ -71,13 +71,14 @@
+     <para>This machine ID adheres to the same format and logic as the
+     D-Bus machine ID.</para>
+ 
+-    <para>This ID uniquely identifies the host. It should be considered "confidential", and must not
+-    be exposed in untrusted environments, in particular on the network. If a stable unique
+-    identifier that is tied to the machine is needed for some application, the machine ID or any
+-    part of it must not be used directly. Instead the machine ID should be hashed with a
+-    cryptographic, keyed hash function, using a fixed, application-specific key. That way the ID
+-    will be properly unique, and derived in a constant way from the machine ID but there will be no
+-    way to retrieve the original machine ID from the application-specific one.</para>
++    <para>This ID uniquely identifies the host. It should be considered "confidential", and must not be exposed in
++    untrusted environments, in particular on the network. If a stable unique identifier that is tied to the machine is
++    needed for some application, the machine ID or any part of it must not be used directly. Instead the machine ID
++    should be hashed with a cryptographic, keyed hash function, using a fixed, application-specific key. That way the
++    ID will be properly unique, and derived in a constant way from the machine ID but there will be no way to retrieve
++    the original machine ID from the application-specific one. The
++    <citerefentry><refentrytitle>sd_id128_get_machine_app_specific</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++    API provides an implementation of such an algorithm.</para>
+ 
+     <para>The
+     <citerefentry><refentrytitle>systemd-machine-id-setup</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml
+index 9a86c24..3938c6d 100644
+--- a/man/sd_id128_get_machine.xml
++++ b/man/sd_id128_get_machine.xml
+@@ -44,6 +44,7 @@
+ 
+   <refnamediv>
+     <refname>sd_id128_get_machine</refname>
++    <refname>sd_id128_get_machine_app_specific</refname>
+     <refname>sd_id128_get_boot</refname>
+     <refname>sd_id128_get_invocation</refname>
+     <refpurpose>Retrieve 128-bit IDs</refpurpose>
+@@ -59,6 +60,12 @@
+       </funcprototype>
+ 
+       <funcprototype>
++        <funcdef>int <function>sd_id128_get_machine_app_specific</function></funcdef>
++        <paramdef>sd_id128_t <parameter>app_id</parameter></paramdef>
++        <paramdef>sd_id128_t *<parameter>ret</parameter></paramdef>
++      </funcprototype>
++
++      <funcprototype>
+         <funcdef>int <function>sd_id128_get_boot</function></funcdef>
+         <paramdef>sd_id128_t *<parameter>ret</parameter></paramdef>
+       </funcprototype>
+@@ -74,11 +81,22 @@
+   <refsect1>
+     <title>Description</title>
+ 
+-    <para><function>sd_id128_get_machine()</function> returns the
+-    machine ID of the executing host. This reads and parses the
+-    <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+-    file. This function caches the machine ID internally to make
+-    retrieving the machine ID a cheap operation.</para>
++    <para><function>sd_id128_get_machine()</function> returns the machine ID of the executing host. This reads and
++    parses the <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
++    file. This function caches the machine ID internally to make retrieving the machine ID a cheap operation. This ID
++    may be used wherever a unique identifier for the local system is needed. However, it is recommended to use this ID
++    as-is only in trusted environments. In untrusted environments it is recommended to derive an application specific
++    ID from this machine ID, in an irreversable (cryptographically secure) way. To make this easy
++    <function>sd_id128_get_machine_app_specific()</function> is provided, see below.</para>
++
++    <para><function>sd_id128_get_machine_app_specific()</function> is similar to
++    <function>sd_id128_get_machine()</function>, but retrieves a machine ID that is specific to the application that is
++    identified by the indicated application ID. It is recommended to use this function instead of
++    <function>sd_id128_get_machine()</function> when passing an ID to untrusted environments, in order to make sure
++    that the original machine ID may not be determined externally. The application-specific ID should be generated via
++    a tool like <command>journalctl --new-id128</command>, and may be compiled into the application. This function will
++    return the same application-specific ID for each combination of machine ID and application ID. Internally, this
++    function calculates HMAC-SHA256 of the application ID, keyed by the machine ID.</para>
+ 
+     <para><function>sd_id128_get_boot()</function> returns the boot ID
+     of the executing kernel. This reads and parses the
+@@ -95,10 +113,10 @@
+     <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details. The
+     ID is cached internally. In future a different mechanism to determine the invocation ID may be added.</para>
+ 
+-    <para>Note that <function>sd_id128_get_boot()</function> and <function>sd_id128_get_invocation()</function> always
+-    return UUID v4 compatible IDs.  <function>sd_id128_get_machine()</function> will also return a UUID v4-compatible
+-    ID on new installations but might not on older.  It is possible to convert the machine ID into a UUID v4-compatible
+-    one. For more information, see
++    <para>Note that <function>sd_id128_get_machine_app_specific()</function>, <function>sd_id128_get_boot()</function>
++    and <function>sd_id128_get_invocation()</function> always return UUID v4 compatible IDs.
++    <function>sd_id128_get_machine()</function> will also return a UUID v4-compatible ID on new installations but might
++    not on older.  It is possible to convert the machine ID into a UUID v4-compatible one. For more information, see
+     <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+ 
+     <para>For more information about the <literal>sd_id128_t</literal>
+@@ -117,13 +135,36 @@
+   <refsect1>
+     <title>Notes</title>
+ 
+-    <para>The <function>sd_id128_get_machine()</function>, <function>sd_id128_get_boot()</function> and
+-    <function>sd_id128_get_invocation()</function> interfaces are available as a shared library, which can be compiled
+-    and linked to with the <literal>libsystemd</literal> <citerefentry
++    <para>The <function>sd_id128_get_machine()</function>, <function>sd_id128_get_machine_app_specific()</function>
++    <function>sd_id128_get_boot()</function> and <function>sd_id128_get_invocation()</function> interfaces are
++    available as a shared library, which can be compiled and linked to with the
++    <literal>libsystemd</literal> <citerefentry
+     project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry> file.</para>
+   </refsect1>
+ 
+   <refsect1>
++    <title>Examples</title>
++
++    <example>
++      <title>Application-specific machine ID</title>
++
++      <para>Here's a simple example for an application specific machine ID:</para>
++
++      <programlisting>#include &lt;systemd/sd-id128.h&gt;
++#include &lt;stdio.h&gt;
++
++#define OUR_APPLICATION_ID SD_ID128_MAKE(c2,73,27,73,23,db,45,4e,a6,3b,b9,6e,79,b5,3e,97)
++
++int main(int argc, char *argv[]) {
++        sd_id128_t id;
++        sd_id128_get_machine_app_specific(OUR_APPLICATION_ID, &amp;id);
++        printf("Our application ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(id));
++        return 0;
++}</programlisting>
++    </example>
++  </refsect1>
++
++  <refsect1>
+     <title>See Also</title>
+ 
+     <para>
+diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
+index d48ef6b..46c4dac 100644
+--- a/src/libsystemd/libsystemd.sym
++++ b/src/libsystemd/libsystemd.sym
+@@ -511,3 +511,8 @@ global:
+         sd_bus_get_exit_on_disconnect;
+         sd_id128_get_invocation;
+ } LIBSYSTEMD_231;
++
++LIBSYSTEMD_233 {
++global:
++        sd_id128_get_machine_app_specific;
++} LIBSYSTEMD_232;
+diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
+index d4450c7..0d673ba 100644
+--- a/src/libsystemd/sd-id128/sd-id128.c
++++ b/src/libsystemd/sd-id128/sd-id128.c
+@@ -27,6 +27,7 @@
+ #include "hexdecoct.h"
+ #include "id128-util.h"
+ #include "io-util.h"
++#include "khash.h"
+ #include "macro.h"
+ #include "random-util.h"
+ #include "util.h"
+@@ -181,3 +182,34 @@ _public_ int sd_id128_randomize(sd_id128_t *ret) {
+         *ret = make_v4_uuid(t);
+         return 0;
+ }
++
++_public_ int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret) {
++        _cleanup_(khash_unrefp) khash *h = NULL;
++        sd_id128_t m, result;
++        const void *p;
++        int r;
++
++        assert_return(ret, -EINVAL);
++
++        r = sd_id128_get_machine(&m);
++        if (r < 0)
++                return r;
++
++        r = khash_new_with_key(&h, "hmac(sha256)", &m, sizeof(m));
++        if (r < 0)
++                return r;
++
++        r = khash_put(h, &app_id, sizeof(app_id));
++        if (r < 0)
++                return r;
++
++        r = khash_digest_data(h, &p);
++        if (r < 0)
++                return r;
++
++        /* We chop off the trailing 16 bytes */
++        memcpy(&result, p, MIN(khash_get_size(h), sizeof(result)));
++
++        *ret = make_v4_uuid(result);
++        return 0;
++}
+diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h
+index ee011b1..6cc8e4a 100644
+--- a/src/systemd/sd-id128.h
++++ b/src/systemd/sd-id128.h
+@@ -39,12 +39,12 @@ union sd_id128 {
+ #define SD_ID128_STRING_MAX 33
+ 
+ char *sd_id128_to_string(sd_id128_t id, char s[SD_ID128_STRING_MAX]);
+-
+ int sd_id128_from_string(const char *s, sd_id128_t *ret);
+ 
+ int sd_id128_randomize(sd_id128_t *ret);
+ 
+ int sd_id128_get_machine(sd_id128_t *ret);
++int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret);
+ int sd_id128_get_boot(sd_id128_t *ret);
+ int sd_id128_get_invocation(sd_id128_t *ret);
+ 
+diff --git a/src/test/test-id128.c b/src/test/test-id128.c
+index 1c8e554..ab5a111 100644
+--- a/src/test/test-id128.c
++++ b/src/test/test-id128.c
+@@ -153,5 +153,11 @@ int main(int argc, char *argv[]) {
+         assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0);
+         assert_se(sd_id128_equal(id, id2));
+ 
++        assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id) >= 0);
++        assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id2) >= 0);
++        assert_se(sd_id128_equal(id, id2));
++        assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8), &id2) >= 0);
++        assert_se(!sd_id128_equal(id, id2));
++
+         return 0;
+ }
+-- 
+2.7.4
+
diff --git a/common/recipes-core/systemd/systemd/0010-core-add-khash-API-to-src-basic-as-wrapper-around-ke.patch b/common/recipes-core/systemd/systemd/0010-core-add-khash-API-to-src-basic-as-wrapper-around-ke.patch
new file mode 100644
index 0000000..2884a3a
--- /dev/null
+++ b/common/recipes-core/systemd/systemd/0010-core-add-khash-API-to-src-basic-as-wrapper-around-ke.patch
@@ -0,0 +1,520 @@
+From 0fe5f3c5d743a7e4c63580a67066935f9e23a2f4 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 17 Nov 2016 17:03:21 +0100
+Subject: [PATCH] core: add "khash" API to src/basic/ (as wrapper around kernel
+ AF_ALG)
+
+Let's take inspiration from bluez's ELL library, and let's move our
+cryptographic primitives away from libgcrypt and towards the kernel's AF_ALG
+cryptographic userspace API.
+
+In the long run we should try to remove the dependency on libgcrypt, in favour
+of using only the kernel's own primitives, however this is unlikely to happen
+anytime soon, as the kernel does not provide Elliptic Curve APIs to userspace
+at this time, and we need them for the DNSSEC cryptographic.
+
+This commit only covers hashing for now, symmetric encryption/decryption or
+even asymetric encryption/decryption is not available for now.
+
+"khash" is little more than a lightweight wrapper around the kernel's AF_ALG
+socket API.
+---
+ .gitignore           |   1 +
+ Makefile.am          |  14 ++-
+ src/basic/khash.c    | 275 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/basic/khash.h    |  53 ++++++++++
+ src/basic/missing.h  |   4 +
+ src/test/test-hash.c |  82 +++++++++++++++
+ 6 files changed, 428 insertions(+), 1 deletion(-)
+ create mode 100644 src/basic/khash.c
+ create mode 100644 src/basic/khash.h
+ create mode 100644 src/test/test-hash.c
+
+diff --git a/.gitignore b/.gitignore
+index 21fcf98..2e39f65 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -198,6 +198,7 @@
+ /test-fs-util
+ /test-fstab-util
+ /test-glob-util
++/test-hash
+ /test-hashmap
+ /test-hexdecoct
+ /test-hostname
+diff --git a/Makefile.am b/Makefile.am
+index 6c350b0..6ea367b 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -934,7 +934,9 @@ libbasic_la_SOURCES = \
+ 	src/basic/alloc-util.h \
+ 	src/basic/alloc-util.c \
+ 	src/basic/formats-util.h \
+-	src/basic/nss-util.h
++	src/basic/nss-util.h \
++	src/basic/khash.h \
++	src/basic/khash.c
+ 
+ nodist_libbasic_la_SOURCES = \
+ 	src/basic/errno-from-name.h \
+@@ -4046,6 +4048,16 @@ tests += \
+ 	test-id128
+ 
+ # ------------------------------------------------------------------------------
++test_hash_SOURCES = \
++	src/test/test-hash.c
++
++test_hash_LDADD = \
++	libsystemd-shared.la
++
++tests += \
++	test-hash
++
++# ------------------------------------------------------------------------------
+ 
+ bin_PROGRAMS += \
+ 	systemd-socket-activate
+diff --git a/src/basic/khash.c b/src/basic/khash.c
+new file mode 100644
+index 0000000..9a2a3ed
+--- /dev/null
++++ b/src/basic/khash.c
+@@ -0,0 +1,275 @@
++/***
++  This file is part of systemd.
++
++  Copyright 2016 Lennart Poettering
++
++  systemd is free software; you can redistribute it and/or modify it
++  under the terms of the GNU Lesser General Public License as published by
++  the Free Software Foundation; either version 2.1 of the License, or
++  (at your option) any later version.
++
++  systemd is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  Lesser General Public License for more details.
++
++  You should have received a copy of the GNU Lesser General Public License
++  along with systemd; If not, see <http://www.gnu.org/licenses/>.
++***/
++
++#include <linux/if_alg.h>
++#include <stdbool.h>
++#include <sys/socket.h>
++
++#include "alloc-util.h"
++#include "fd-util.h"
++#include "hexdecoct.h"
++#include "khash.h"
++#include "macro.h"
++#include "missing.h"
++#include "string-util.h"
++#include "util.h"
++
++/* On current kernels the maximum digest (according to "grep digestsize /proc/crypto | sort -u") is actually 32, but
++ * let's add some extra room, the few wasted bytes don't really matter... */
++#define LONGEST_DIGEST 128
++
++struct khash {
++        int fd;
++        char *algorithm;
++        uint8_t digest[LONGEST_DIGEST+1];
++        size_t digest_size;
++        bool digest_valid;
++};
++
++int khash_new_with_key(khash **ret, const char *algorithm, const void *key, size_t key_size) {
++        union {
++                struct sockaddr sa;
++                struct sockaddr_alg alg;
++        } sa = {
++                .alg.salg_family = AF_ALG,
++                .alg.salg_type = "hash",
++        };
++
++        _cleanup_(khash_unrefp) khash *h = NULL;
++        _cleanup_close_ int fd = -1;
++        ssize_t n;
++
++        assert(ret);
++        assert(key || key_size == 0);
++
++        /* Filter out an empty algorithm early, as we do not support an algorithm by that name. */
++        if (isempty(algorithm))
++                return -EINVAL;
++
++        /* Overly long hash algorithm names we definitely do not support */
++        if (strlen(algorithm) >= sizeof(sa.alg.salg_name))
++                return -EOPNOTSUPP;
++
++        fd = socket(AF_ALG, SOCK_SEQPACKET|SOCK_CLOEXEC, 0);
++        if (fd < 0)
++                return -errno;
++
++        strcpy((char*) sa.alg.salg_name, algorithm);
++        if (bind(fd, &sa.sa, sizeof(sa)) < 0) {
++                if (errno == ENOENT)
++                        return -EOPNOTSUPP;
++                return -errno;
++        }
++
++        if (key) {
++                if (setsockopt(fd, SOL_ALG, ALG_SET_KEY, key, key_size) < 0)
++                        return -errno;
++        }
++
++        h = new0(khash, 1);
++        if (!h)
++                return -ENOMEM;
++
++        h->fd = accept4(fd, NULL, 0, SOCK_CLOEXEC);
++        if (h->fd < 0)
++                return -errno;
++
++        h->algorithm = strdup(algorithm);
++        if (!h->algorithm)
++                return -ENOMEM;
++
++        /* Temporary fix for rc kernel bug: https://bugzilla.redhat.com/show_bug.cgi?id=1395896 */
++        (void) send(h->fd, NULL, 0, 0);
++
++        /* Figure out the digest size */
++        n = recv(h->fd, h->digest, sizeof(h->digest), 0);
++        if (n < 0)
++                return -errno;
++        if (n >= LONGEST_DIGEST) /* longer than what we expected? If so, we don't support this */
++                return -EOPNOTSUPP;
++
++        h->digest_size = (size_t) n;
++        h->digest_valid = true;
++
++        /* Temporary fix for rc kernel bug: https://bugzilla.redhat.com/show_bug.cgi?id=1395896 */
++        (void) send(h->fd, NULL, 0, 0);
++
++        *ret = h;
++        h = NULL;
++
++        return 0;
++}
++
++int khash_new(khash **ret, const char *algorithm) {
++        return khash_new_with_key(ret, algorithm, NULL, 0);
++}
++
++khash* khash_unref(khash *h) {
++        if (!h)
++                return NULL;
++
++        safe_close(h->fd);
++        free(h->algorithm);
++        free(h);
++
++        return NULL;
++}
++
++int khash_dup(khash *h, khash **ret) {
++        _cleanup_(khash_unrefp) khash *copy = NULL;
++
++        assert(h);
++        assert(ret);
++
++        copy = newdup(khash, h, 1);
++        if (!copy)
++                return -ENOMEM;
++
++        copy->fd = -1;
++        copy->algorithm = strdup(h->algorithm);
++        if (!copy)
++                return -ENOMEM;
++
++        copy->fd = accept4(h->fd, NULL, 0, SOCK_CLOEXEC);
++        if (copy->fd < 0)
++                return -errno;
++
++        *ret = copy;
++        copy = NULL;
++
++        return 0;
++}
++
++const char *khash_get_algorithm(khash *h) {
++        assert(h);
++
++        return h->algorithm;
++}
++
++size_t khash_get_size(khash *h) {
++        assert(h);
++
++        return h->digest_size;
++}
++
++int khash_reset(khash *h) {
++        ssize_t n;
++
++        assert(h);
++
++        n = send(h->fd, NULL, 0, 0);
++        if (n < 0)
++                return -errno;
++
++        h->digest_valid = false;
++
++        return 0;
++}
++
++int khash_put(khash *h, const void *buffer, size_t size) {
++        ssize_t n;
++
++        assert(h);
++        assert(buffer || size == 0);
++
++        if (size <= 0)
++                return 0;
++
++        n = send(h->fd, buffer, size, MSG_MORE);
++        if (n < 0)
++                return -errno;
++
++        h->digest_valid = false;
++
++        return 0;
++}
++
++int khash_put_iovec(khash *h, const struct iovec *iovec, size_t n) {
++        struct msghdr mh = {
++                mh.msg_iov = (struct iovec*) iovec,
++                mh.msg_iovlen = n,
++        };
++        ssize_t k;
++
++        assert(h);
++        assert(iovec || n == 0);
++
++        if (n <= 0)
++                return 0;
++
++        k = sendmsg(h->fd, &mh, MSG_MORE);
++        if (k < 0)
++                return -errno;
++
++        h->digest_valid = false;
++
++        return 0;
++}
++
++static int retrieve_digest(khash *h) {
++        ssize_t n;
++
++        assert(h);
++
++        if (h->digest_valid)
++                return 0;
++
++        n = recv(h->fd, h->digest, h->digest_size, 0);
++        if (n < 0)
++                return n;
++        if ((size_t) n != h->digest_size) /* digest size changed? */
++                return -EIO;
++
++        h->digest_valid = true;
++
++        return 0;
++}
++
++int khash_digest_data(khash *h, const void **ret) {
++        int r;
++
++        assert(h);
++        assert(ret);
++
++        r = retrieve_digest(h);
++        if (r < 0)
++                return r;
++
++        *ret = h->digest;
++        return 0;
++}
++
++int khash_digest_string(khash *h, char **ret) {
++        int r;
++        char *p;
++
++        assert(h);
++        assert(ret);
++
++        r = retrieve_digest(h);
++        if (r < 0)
++                return r;
++
++        p = hexmem(h->digest, h->digest_size);
++        if (!p)
++                return -ENOMEM;
++
++        *ret = p;
++        return 0;
++}
+diff --git a/src/basic/khash.h b/src/basic/khash.h
+new file mode 100644
+index 0000000..f404a68
+--- /dev/null
++++ b/src/basic/khash.h
+@@ -0,0 +1,53 @@
++#pragma once
++
++/***
++  This file is part of systemd.
++
++  Copyright 2016 Lennart Poettering
++
++  systemd is free software; you can redistribute it and/or modify it
++  under the terms of the GNU Lesser General Public License as published by
++  the Free Software Foundation; either version 2.1 of the License, or
++  (at your option) any later version.
++
++  systemd is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  Lesser General Public License for more details.
++
++  You should have received a copy of the GNU Lesser General Public License
++  along with systemd; If not, see <http://www.gnu.org/licenses/>.
++***/
++
++#include <inttypes.h>
++#include <sys/types.h>
++#include <sys/uio.h>
++
++#include "macro.h"
++
++typedef struct khash khash;
++
++/* For plain hash functions. Hash functions commonly supported on today's kernels are: crc32c, crct10dif, crc32,
++ * sha224, sha256, sha512, sha384, sha1, md5, md4, sha3-224, sha3-256, sha3-384, sha3-512, and more.*/
++int khash_new(khash **ret, const char *algorithm);
++
++/* For keyed hash functions. Hash functions commonly supported on today's kernels are: hmac(sha256), cmac(aes),
++ * cmac(des3_ede), hmac(sha3-512), hmac(sha3-384), hmac(sha3-256), hmac(sha3-224), hmac(rmd160), hmac(rmd128),
++ * hmac(sha224), hmac(sha512), hmac(sha384), hmac(sha1), hmac(md5), and more. */
++int khash_new_with_key(khash **ret, const char *algorithm, const void *key, size_t key_size);
++
++int khash_dup(khash *h, khash **ret);
++khash* khash_unref(khash *h);
++
++const char *khash_get_algorithm(khash *h);
++size_t khash_get_size(khash *h);
++
++int khash_reset(khash *h);
++
++int khash_put(khash *h, const void *buffer, size_t size);
++int khash_put_iovec(khash *h, const struct iovec *iovec, size_t n);
++
++int khash_digest_data(khash *h, const void **ret);
++int khash_digest_string(khash *h, char **ret);
++
++DEFINE_TRIVIAL_CLEANUP_FUNC(khash*, khash_unref);
+diff --git a/src/basic/missing.h b/src/basic/missing.h
+index 8833617..1502b3f 100644
+--- a/src/basic/missing.h
++++ b/src/basic/missing.h
+@@ -1085,4 +1085,8 @@ typedef int32_t key_serial_t;
+ #define exp10(x) (exp((x) * log(10)))
+ #endif /* __UCLIBC__ */
+
++#ifndef SOL_ALG
++#define SOL_ALG 279
++#endif
++
+ #include "missing_syscall.h"
+diff --git a/src/test/test-hash.c b/src/test/test-hash.c
+new file mode 100644
+index 0000000..1972b94
+--- /dev/null
++++ b/src/test/test-hash.c
+@@ -0,0 +1,82 @@
++/***
++  This file is part of systemd.
++
++  Copyright 2016 Lennart Poettering
++
++  systemd is free software; you can redistribute it and/or modify it
++  under the terms of the GNU Lesser General Public License as published by
++  the Free Software Foundation; either version 2.1 of the License, or
++  (at your option) any later version.
++
++  systemd is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  Lesser General Public License for more details.
++
++  You should have received a copy of the GNU Lesser General Public License
++  along with systemd; If not, see <http://www.gnu.org/licenses/>.
++***/
++
++#include "alloc-util.h"
++#include "log.h"
++#include "string-util.h"
++#include "khash.h"
++
++int main(int argc, char *argv[]) {
++        _cleanup_(khash_unrefp) khash *h = NULL, *copy = NULL;
++        _cleanup_free_ char *s = NULL;
++
++        log_set_max_level(LOG_DEBUG);
++
++        assert_se(khash_new(&h, NULL) == -EINVAL);
++        assert_se(khash_new(&h, "") == -EINVAL);
++        assert_se(khash_new(&h, "foobar") == -EOPNOTSUPP);
++
++        assert_se(khash_new(&h, "sha256") >= 0);
++        assert_se(khash_get_size(h) == 32);
++        assert_se(streq(khash_get_algorithm(h), "sha256"));
++
++        assert_se(khash_digest_string(h, &s) >= 0);
++        assert_se(streq(s, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));
++        s = mfree(s);
++
++        assert_se(khash_put(h, "foobar", 6) >= 0);
++        assert_se(khash_digest_string(h, &s) >= 0);
++        assert_se(streq(s, "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"));
++        s = mfree(s);
++
++        assert_se(khash_put(h, "piep", 4) >= 0);
++        assert_se(khash_digest_string(h, &s) >= 0);
++        assert_se(streq(s, "f114d872b5ea075d3be9040d0b7a429514b3f9324a8e8e3dc3fb24c34ee56bea"));
++        s = mfree(s);
++
++        assert_se(khash_put(h, "foo", 3) >= 0);
++        assert_se(khash_dup(h, &copy) >= 0);
++
++        assert_se(khash_put(h, "bar", 3) >= 0);
++        assert_se(khash_put(copy, "bar", 3) >= 0);
++
++        assert_se(khash_digest_string(h, &s) >= 0);
++        assert_se(streq(s, "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"));
++        s = mfree(s);
++
++        assert_se(khash_digest_string(copy, &s) >= 0);
++        assert_se(streq(s, "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"));
++        s = mfree(s);
++
++        h = khash_unref(h);
++
++        assert_se(khash_new_with_key(&h, "hmac(sha256)", "quux", 4) >= 0);
++        assert_se(khash_get_size(h) == 32);
++        assert_se(streq(khash_get_algorithm(h), "hmac(sha256)"));
++
++        assert_se(khash_digest_string(h, &s) >= 0);
++        assert_se(streq(s, "abed9f8218ab473f77218a6a7d39abf1d21fa46d0700c4898e330ba88309d5ae"));
++        s = mfree(s);
++
++        assert_se(khash_put(h, "foobar", 6) >= 0);
++        assert_se(khash_digest_string(h, &s) >= 0);
++        assert_se(streq(s, "33f6c70a60db66007d5325d5d1dea37c371354e5b83347a59ad339ce9f4ba3dc"));
++
++        return 0;
++}
+-- 
+2.7.4
+
diff --git a/common/recipes-core/systemd/systemd_%.bbappend b/common/recipes-core/systemd/systemd_%.bbappend
index 52edfc5..3208ae3 100644
--- a/common/recipes-core/systemd/systemd_%.bbappend
+++ b/common/recipes-core/systemd/systemd_%.bbappend
@@ -17,6 +17,9 @@
 SRC_URI += "file://0006-journal-Create-journald-dbus-object.patch"
 SRC_URI += "file://0007-journal-Add-Synchronize-dbus-method.patch"
 SRC_URI += "${@mf_enabled(d, 'obmc-ubi-fs', 'file://software.conf')}"
+SRC_URI += "file://0008-man-update-machine-id-5-with-a-note-about-privacy-46.patch"
+SRC_URI += "file://0009-sd-id128-add-new-sd_id128_get_machine_app_specific-A.patch"
+SRC_URI += "file://0010-core-add-khash-API-to-src-basic-as-wrapper-around-ke.patch"
 
 RRECOMMENDS_${PN} += "obmc-targets"
 FILES_${PN} += "${libdir}/systemd/network/default.network"