1
$\begingroup$

I have a Rijndael function that I've implemented as a JavaScript port of a C reference implementation in a technical specification for the MILENAGE algorithm (ETSI TS 135 206 V14.0.0 (2017-04)). My JavaScript port works fine, as verified by successful authentication of actual SIM cards.

Instead of using something implemented in JavaScript, I'm wondering if I can find an equivalent cipher within Node.js/OpenSSL's built-in ciphers to (1) avoid rolling my own (2) take advantage of potential performance gains of using a compiled implementation.

I didn't catch the TS mentioning a particular flavour of Rijndael being used in the reference implementation (are there even multiple flavours of Rijndael?). Is the hard-coded S box table always like that?

I'm also not too clear on what the relationship of AES and Rijndael is. If AES is based on Rijndael, can I find an AES flavour that matches the reference Rijndael implementation I have?

When I enumerated the available ciphers in Node.js's crypto library, I got:

> require('crypto').getCiphers()
[ 'CAST-cbc',
  'aes-128-cbc',
  'aes-128-cbc-hmac-sha1',
  'aes-128-ccm',
  'aes-128-cfb',
  'aes-128-cfb1',
  'aes-128-cfb8',
  'aes-128-ctr',
  'aes-128-ecb',
  'aes-128-gcm',
  'aes-128-ofb',
  'aes-128-xts',
  'aes-192-cbc',
  'aes-192-ccm',
  'aes-192-cfb',
  'aes-192-cfb1',
  'aes-192-cfb8',
  'aes-192-ctr',
  'aes-192-ecb',
  'aes-192-gcm',
  'aes-192-ofb',
  'aes-256-cbc',
  'aes-256-cbc-hmac-sha1',
  'aes-256-ccm',
  'aes-256-cfb',
  'aes-256-cfb1',
  'aes-256-cfb8',
  'aes-256-ctr',
  'aes-256-ecb',
  'aes-256-gcm',
  'aes-256-ofb',
  'aes-256-xts',
  'aes128',
  'aes192',
  'aes256',
  'bf',
  'bf-cbc',
  'bf-cfb',
  'bf-ecb',
  'bf-ofb',
  'blowfish',
  'camellia-128-cbc',
  'camellia-128-cfb',
  'camellia-128-cfb1',
  'camellia-128-cfb8',
  'camellia-128-ecb',
  'camellia-128-ofb',
  'camellia-192-cbc',
  'camellia-192-cfb',
  'camellia-192-cfb1',
  'camellia-192-cfb8',
  'camellia-192-ecb',
  'camellia-192-ofb',
  'camellia-256-cbc',
  'camellia-256-cfb',
  'camellia-256-cfb1',
  'camellia-256-cfb8',
  'camellia-256-ecb',
  'camellia-256-ofb',
  'camellia128',
  'camellia192',
  'camellia256',
  'cast',
  'cast-cbc',
  'cast5-cbc',
  'cast5-cfb',
  'cast5-ecb',
  'cast5-ofb',
  'des',
  'des-cbc',
  'des-cfb',
  'des-cfb1',
  'des-cfb8',
  'des-ecb',
  'des-ede',
  'des-ede-cbc',
  'des-ede-cfb',
  'des-ede-ofb',
  'des-ede3',
  'des-ede3-cbc',
  'des-ede3-cfb',
  'des-ede3-cfb1',
  'des-ede3-cfb8',
  'des-ede3-ofb',
  'des-ofb',
  'des3',
  'desx',
  'desx-cbc',
  'id-aes128-CCM',
  'id-aes128-GCM',
  'id-aes128-wrap',
  'id-aes192-CCM',
  'id-aes192-GCM',
  'id-aes192-wrap',
  'id-aes256-CCM',
  'id-aes256-GCM',
  'id-aes256-wrap',
  'id-smime-alg-CMS3DESwrap',
  'idea',
  'idea-cbc',
  'idea-cfb',
  'idea-ecb',
  'idea-ofb',
  'rc2',
  'rc2-40-cbc',
  'rc2-64-cbc',
  'rc2-cbc',
  'rc2-cfb',
  'rc2-ecb',
  'rc2-ofb',
  'rc4',
  'rc4-40',
  'rc4-hmac-md5',
  'seed',
  'seed-cbc',
  'seed-cfb',
  'seed-ecb',
  'seed-ofb' ]

I had tested a random bunch (based on uneducated guessing) of AES ciphers from above to see if I could get identical outputs to the reference Rijndael implementation but had failed.

Any pointers?

$\endgroup$
  • 1
    $\begingroup$ Assuming nodejs goes through OpenSSLs 'EVP' API, which is the one that uses the style of names you show, in addition to assembler code on most platforms it can use 'hardware' or at least firmware instructions on recent Intel/AMD CPUs for sure and I believe ARM also. In addition to raw performance, these are better protected against timing and possibly other side-channel attacks. $\endgroup$ – dave_thompson_085 Jul 7 '17 at 3:36
2
$\begingroup$

AES is Rijndael, but only for blocksize 128 and keysizes 128, 192, 256. Rijndael also supports blocks of size 256 e.g. and other (intermediate) keysizes. But AES is the official standard and this standard only called for one block size 128 and those three keysizes. The S-boxes are the same and quite fixed, yes. Any goood Rijndael implementation shoudl be compatible with AES, with the right parameters.

aes-128-ecb should be standard AES for 128 bit keys. Others are modes with iv's as well, ecb is just "encrypt a block at the time", no mixing between blocks. ditto for other keysizes 192 and 256. I suppose aes128 should be the same as aes-128-ecb? I don't know Node.js at all, so maybe not.

$\endgroup$
  • 1
    $\begingroup$ OpenSSL EVP (and I ass-u-me nodejs) for block modes (ECB, CBC) uses PKCS5/7-type padding (01, 02 02, 03 03 03, etc). OpenSSL commandline by default does password-based derivation (approximately but not exactly PBKDF1) of key, and IV when applicable, but on the API you normally have to ask for this separately. These could confuse comparisons. $\endgroup$ – dave_thompson_085 Jul 7 '17 at 3:37
  • $\begingroup$ aes-128-ecb was indeed the equivalent! Dropping implementation notes here for those interested: The Node.js crypto library provides two ways of instantiating a cipher object: (1) crypto.createCipher(<name>, <password>) and (2) crypto.createCipheriv(<name>, <key>, <IV>). In (1), the key and IV are derived from the password. In (2), the raw key and IV are passed. However, one tricky thing was that the Node.js documentation doesn't mention that you should pass a zero-length buffer for the IV since the ECB cipher doesn't utilize IV (via stackoverflow.com/a/41135415/23501) $\endgroup$ – Ateş Göral Jul 7 '17 at 5:31
  • 1
    $\begingroup$ So the final, equivalent (to the Rijndael) implementation is: const crypto = require('crypto'); const cipher = crypto.createCipheriv('aes-128-ecb', key, Buffer.alloc(0)); const output = cipher.update(data); (where the key is also 128-bit) $\endgroup$ – Ateş Göral Jul 7 '17 at 5:34
  • $\begingroup$ ecb is the worst mode to use, but you probably knew that already.... $\endgroup$ – dandavis Jul 7 '17 at 21:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.