Bug 1323520

Summary: Userspace crypto API fails to calculate HMAC, returns error 95 (EOPNOTSUPP)
Product: [Fedora] Fedora Reporter: Jeffrey Walton <noloader>
Component: kernelAssignee: Kernel Maintainer List <kernel-maint>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 24CC: gansalmon, itamar, jonathan, kernel-maint, labbott, madhu.chinakonda, mchehab, noloader
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-11-17 01:31:41 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Attachments:
Description Flags
Test program to calculate HMAC using userland crypto API and AF_ALG socket none

Description Jeffrey Walton 2016-04-03 22:34:26 UTC
Created attachment 1143110 [details]
Test program to calculate HMAC using userland crypto API and AF_ALG socket

The Linux kernel provides a number of crypto modules. The crypto is exposed in a userspace API through the AF_ALG socket domain.

According to the kernel docs (http://lxr.free-electrons.com/source/Documentation/crypto/crypto-API-userspace.txt?v=4.0):

 16 Some details of the in-kernel kernel crypto API aspects do not
 17 apply to user space, however. This includes the difference between synchronous
 18 and asynchronous invocations. The user space API call is fully synchronous.

And:

 51 To interact with the kernel crypto API, a Netlink socket must be created by
 52 the user space application. User space invokes the cipher operation with the
 53 send/write system call family. The result of the cipher operation is obtained
 54 with the read/recv system call family.

I'm trying to calculate a SHA256 HAMC of RFC 4231 Test Case 1 using the synchronous API. The program is attached, and it uses SHA256 HMAC because the driver is available.

Creating the socket, binding it, setting the HMAC key and writing data work as advertised. However, reading the calculated HMAC with read() is failing with error 95 (EOPNOTSUPP).

Changing to send() and recv() results in the same error. Adding options like MSG_WAITALL does not help the failure.

**********

The relevant parts of the program with most error checking omitted (but present in the attached file) is:

	int r,s;

	s = socket(AF_ALG, SOCK_SEQPACKET, 0);

	const struct sockaddr_alg sa = {
		.salg_family = AF_ALG,
		.salg_type = "hash",
		.salg_name = "hmac(sha256)"
	};

	r = bind(s, (const struct sockaddr *)&sa, sizeof(sa));

	/* RFC 4231, Test Case 1 key */
	r = setsockopt(s, SOL_ALG, ALG_SET_KEY,
  		"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
		"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20);

	/* RFC 4231, Test Case 1 data */
	r = (int)write(s, "Hi There", 8);

	unsigned char mac[32];
	r = (int)read(s, mac, sizeof(mac));
	if (r == -1) {
		fprintf(stderr, "Failed to read mac: %d\n", errno);
	}

**********

$ uname -a
Linux fedora-23-x64 4.4.6-300.fc23.x86_64 #1 SMP Wed Mar 16 22:10:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

**********

List available crypto gear:

$ cat /proc/crypto | egrep '^(name|driver|$)'
name         : sha384
driver       : sha384-avx

name         : sha512
driver       : sha512-avx

name         : sha384
driver       : sha384-ssse3

name         : sha512
driver       : sha512-ssse3

name         : sha384
driver       : sha384-generic

name         : sha512
driver       : sha512-generic

name         : crct10dif
driver       : crct10dif-pclmul

name         : crc32
driver       : crc32-pclmul

name         : crc32c
driver       : crc32c-intel

name         : __ctr-aes-aesni
driver       : cryptd(__driver-ctr-aes-aesni)

name         : ctr(aes)
driver       : ctr-aes-aesni

name         : __gcm-aes-aesni
driver       : cryptd(__driver-gcm-aes-aesni)

name         : rfc4106(gcm(aes))
driver       : rfc4106-gcm-aesni

name         : __gcm-aes-aesni
driver       : __driver-gcm-aes-aesni

name         : xts(aes)
driver       : xts-aes-aesni

name         : lrw(aes)
driver       : lrw-aes-aesni

name         : __xts-aes-aesni
driver       : __driver-xts-aes-aesni

name         : __lrw-aes-aesni
driver       : __driver-lrw-aes-aesni

name         : pcbc(aes)
driver       : pcbc-aes-aesni

name         : ctr(aes)
driver       : ctr-aes-aesni

name         : __ctr-aes-aesni
driver       : __driver-ctr-aes-aesni

name         : cbc(aes)
driver       : cbc-aes-aesni

name         : __ecb-aes-aesni
driver       : cryptd(__driver-ecb-aes-aesni)

name         : ecb(aes)
driver       : ecb-aes-aesni

name         : __cbc-aes-aesni
driver       : __driver-cbc-aes-aesni

name         : __ecb-aes-aesni
driver       : __driver-ecb-aes-aesni

name         : __aes-aesni
driver       : __driver-aes-aesni

name         : aes
driver       : aes-aesni

name         : jitterentropy_rng
driver       : jitterentropy_rng

name         : stdrng
driver       : drbg_nopr_hmac_sha256

name         : stdrng
driver       : drbg_nopr_hmac_sha512

name         : stdrng
driver       : drbg_nopr_hmac_sha384

name         : stdrng
driver       : drbg_nopr_hmac_sha1

name         : stdrng
driver       : drbg_nopr_sha256

name         : stdrng
driver       : drbg_nopr_sha512

name         : stdrng
driver       : drbg_nopr_sha384

name         : stdrng
driver       : drbg_nopr_sha1

name         : stdrng
driver       : drbg_nopr_ctr_aes256

name         : stdrng
driver       : drbg_nopr_ctr_aes192

name         : stdrng
driver       : drbg_nopr_ctr_aes128

name         : hmac(sha256)
driver       : hmac(sha256-generic)

name         : stdrng
driver       : drbg_pr_hmac_sha256

name         : stdrng
driver       : drbg_pr_hmac_sha512

name         : stdrng
driver       : drbg_pr_hmac_sha384

name         : stdrng
driver       : drbg_pr_hmac_sha1

name         : stdrng
driver       : drbg_pr_sha256

name         : stdrng
driver       : drbg_pr_sha512

name         : stdrng
driver       : drbg_pr_sha384

name         : stdrng
driver       : drbg_pr_sha1

name         : stdrng
driver       : drbg_pr_ctr_aes256

name         : stdrng
driver       : drbg_pr_ctr_aes192

name         : stdrng
driver       : drbg_pr_ctr_aes128

name         : lzo
driver       : lzo-generic

name         : crct10dif
driver       : crct10dif-generic

name         : crc32c
driver       : crc32c-generic

name         : aes
driver       : aes-generic

name         : sha224
driver       : sha224-generic

name         : sha256
driver       : sha256-generic

name         : sha1
driver       : sha1-generic

name         : md5
driver       : md5-generic

name         : digest_null
driver       : digest_null-generic

name         : compress_null
driver       : compress_null-generic

name         : ecb(cipher_null)
driver       : ecb-cipher_null

name         : cipher_null
driver       : cipher_null-generic

name         : aes
driver       : aes-asm

Comment 1 Jeffrey Walton 2016-04-04 20:36:45 UTC
Its not clear to me where EOPNOTSUPP is coming from:

    $ cd linux/crypto
    $ grep -IR EOPNOTSUPP *
    asymmetric_keys/x509_public_key.c:    return -EOPNOTSUPP;
    drbg.c:    ret = -EOPNOTSUPP;

Perhaps there's some patches being used by Fedora that are not present in Torvald's GitHub.

Comment 2 Laura Abbott 2016-09-23 19:57:49 UTC
*********** MASS BUG UPDATE **************
 
We apologize for the inconvenience.  There is a large number of bugs to go through and several of them have gone stale.  Due to this, we are doing a mass bug update across all of the Fedora 23 kernel bugs.
 
Fedora 23 has now been rebased to 4.7.4-100.fc23.  Please test this kernel update (or newer) and let us know if you issue has been resolved or if it is still present with the newer kernel.
 
If you have moved on to Fedora 24 or 25, and are still experiencing this issue, please change the version to Fedora 24 or 25.
 
If you experience different issues, please open a new bug report for those.

Comment 3 Jeffrey Walton 2016-09-24 00:21:38 UTC
Still a problem in Fedora 24 on i686. I don't have an Fedora amd64 VM up at the moment, so I can't test it right now.

Comment 4 Laura Abbott 2016-11-17 01:31:41 UTC
You need to call accept and read/write to that socket. See http://lwn.net/Articles/410833/ . With that your program works fine.