Hi, This is a first diff of a series that brings support for the Galois/Counter Mode for AES in OpenBSD. Intro ===== For those unfamiliar with GCM, I'm going to quote Wikipedia[1]: GCM mode (Galois/Counter Mode) is a mode of operation for symmetri key cryptographic block ciphers. It is an authenticated encryption algorithm designed to provide both authentication and secrecy. GCM mode is defined for block ciphers with a block size of 128 bits. GMAC is an authentication-only variant of the GCM. So GCM is an emerging standard for IPsec that is approved by NIST in the NIST Special Publication 800-38D[2]. It's unencumbered by patents. GCM is cryptographically secure as long as underlying cipher is secure; it heavily relies on uniqueness and non-repeating of the Initialization Vector. Also use of IKE is mandatory for GCM. Quoting RFC 4106[3]: Because reusing an nonce/key combination destroys the security guarantees of AES-GCM mode, it can be difficult to use this mode securely when using statically configured keys. For safety's sake, implementations MUST use an automated key management system, such as the Internet Key Exchange (IKE) [RFC2409], to ensure that this requirement is met. "Authentication weaknesses in GCM" by Niels Ferguson[4] describes some of the potentian issues with GCM in detail. Implementation details ====================== As this is the first time a combined authentication-encryption transformation hits OpenBSD kernel, I chose to split to split it into two parts: encryption transformation and authentication hash, AES-GCM and AES-GMAC respectively. AES-GCM part is fairly simple and it reuses AES-CTR code to do key generation, encryption and decryption. IV handling is almost the same, except that GCM spec requires to start counter with 1. Here I have to note that AES-GCM is a stream cipher hence it has a block size of "1". Now GMAC is a bit different to HMAC-style functions. Highlights: - uses one round of ...
I hope this will clarify the text above:
- requires input date to be split into blocks of 16 bytes with
the last block padded with zeros, otherwise it yeilds erroneous
value, i.e.:
given block C of 16 bytes that is a concatenation of chunks
A and B (C = A || B), then GMAC(C, Z) =/= GMAC(B, GMAC(A, Z)),
where GMAC(X, Y) denotes GMAC application to the chunk X and
state block Y, Z denotes initial zero block.
\o/ panic: unaligned access This is exactly the rdate/ntp.c problem again. You can't assume that a char array is int32-aligned. Also, why is this finalization not done for AES_GCM_16 and AES_GMAC? This doesn't seem right. AES_GCM_16 and AES_GMAC are missing from swcr_freesession(). AES_GMAC is missing from swcr_process() and swcr_init(). -- Christian "naddy" Weisgerber naddy@mips.inka.de
true! well, almost. let me tell you something about GCC: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33594 excerpt: The cause of the change in alignment seems to be the following: - gcc 4.x allocates stack in cfgexpand.c, function expand_one_stack_var() - this calls get_decl_align_unit(), also in cfgexpand.c - the alignment is then read using macro DECL_ALIGN, which returns the alignment of the type - a further revision is made using macro LOCAL_ALIGNMENT - however, LOCAL_ALIGNMENT is not defined for the sparc architecture (in gcc/config/sparc.h), causing the alignment to remain as default This was fixed in 4.3: http://gcc.gnu.org/viewcvs/trunk/gcc/config/sparc/sparc.h?r1=127157&r2=129385&... woohoo! Index: conf/files =================================================================== RCS file: /home/cvs/src/sys/conf/files,v retrieving revision 1.499 diff -u -p -r1.499 files --- conf/files 31 Jul 2010 08:33:19 -0000 1.499 +++ conf/files 3 Aug 2010 17:42:09 -0000 @@ -897,6 +897,7 @@ file crypto/arc4.c file crypto/michael.c wlan file crypto/cmac.c wlan file crypto/hmac.c wlan | (softraid & crypto) +file crypto/gmac.c (inet & ipsec) | crypto file crypto/key_wrap.c wlan file crypto/idgen.c inet6 | nfsclient | nfsserver file netatalk/aarp.c netatalk Index: crypto/cryptodev.c =================================================================== RCS file: /home/cvs/src/sys/crypto/cryptodev.c,v retrieving revision 1.73 diff -u -p -r1.73 cryptodev.c --- crypto/cryptodev.c 21 Jul 2010 18:44:01 -0000 1.73 +++ crypto/cryptodev.c 26 Jul 2010 11:26:07 -0000 @@ -178,6 +178,9 @@ cryptof_ioctl(struct file *fp, u_long cm case CRYPTO_AES_XTS: txform = &enc_xform_aes_xts; break; + case CRYPTO_AES_GCM_16: + txform = &enc_xform_aes_gcm; + break; case CRYPTO_ARC4: txform = &enc_xform_arc4; break; Index: crypto/cryptodev.h =================================================================== RCS file: ...
Ah, that's a good find. I had been looking at LOCAL_ALIGNMENT before, but wasn't sure that was the way to go. I'm testing the diff from that bug report now on sparc64 and an equivalent diff on hppa.
Latest version. No changes since the last one, except for the fixed CRYPTO_ALGORITHM_MAX. OK to commit? :) Index: conf/files =================================================================== RCS file: /home/cvs/src/sys/conf/files,v retrieving revision 1.499 diff -u -p -u -p -r1.499 files --- conf/files 31 Jul 2010 08:33:19 -0000 1.499 +++ conf/files 3 Aug 2010 17:42:09 -0000 @@ -897,6 +897,7 @@ file crypto/arc4.c file crypto/michael.c wlan file crypto/cmac.c wlan file crypto/hmac.c wlan | (softraid & crypto) +file crypto/gmac.c (inet & ipsec) | crypto file crypto/key_wrap.c wlan file crypto/idgen.c inet6 | nfsclient | nfsserver file netatalk/aarp.c netatalk Index: crypto/cryptodev.c =================================================================== RCS file: /home/cvs/src/sys/crypto/cryptodev.c,v retrieving revision 1.73 diff -u -p -u -p -r1.73 cryptodev.c --- crypto/cryptodev.c 21 Jul 2010 18:44:01 -0000 1.73 +++ crypto/cryptodev.c 26 Jul 2010 11:26:07 -0000 @@ -178,6 +178,9 @@ cryptof_ioctl(struct file *fp, u_long cm case CRYPTO_AES_XTS: txform = &enc_xform_aes_xts; break; + case CRYPTO_AES_GCM_16: + txform = &enc_xform_aes_gcm; + break; case CRYPTO_ARC4: txform = &enc_xform_arc4; break; Index: crypto/cryptodev.h =================================================================== RCS file: /home/cvs/src/sys/crypto/cryptodev.h,v retrieving revision 1.51 diff -u -p -u -p -r1.51 cryptodev.h --- crypto/cryptodev.h 23 Jun 2010 09:26:32 -0000 1.51 +++ crypto/cryptodev.h 24 Aug 2010 09:19:42 -0000 @@ -105,7 +105,12 @@ #define CRYPTO_SHA2_512_HMAC 20 #define CRYPTO_AES_CTR 21 #define CRYPTO_AES_XTS 22 -#define CRYPTO_ALGORITHM_MAX 22 /* Keep updated */ +#define CRYPTO_AES_GCM_16 23 +#define CRYPTO_AES_128_GMAC 24 +#define CRYPTO_AES_192_GMAC 25 +#define CRYPTO_AES_256_GMAC 26 +#define CRYPTO_AES_GMAC 27 +#define CRYPTO_ALGORITHM_MAX 27 /* Keep updated */ /* Algorithm flags */ ...
