First, you should never be using CBC mode for a number of reasons, including no 
tamper detection, and potential issues with padding attacks, such as ones that 
have hit TLS in the past.

Instead, you should be using a more modern encryption mode that does integrity 
checking by default.

NimCrypto isn't something I'd recommend; its maintainers don't seem to have too 
deep an understanding of cryptography (or perhaps don't care much about people 
building secure systems on top of their library). They only support one modern 
mode, and they implement it incorrectly. They seem not to be in a hurry to fix 
this.

Meanwhile, Nim ships working with OpenSSL out of the box. OpenSSL has GCM built 
in, which is the default symmetric cipher suite for AES. On most platforms, 
OpenSSL will use hardware accelerated code for this. However, Nim's standard 
libraries don't expose it directly.

I've wrapped some of the AES bits in OpenSSL for my own needs, which you're 
welcome to use if you like: <https://github.com/crashappsec/nimutils>

I've not tried to make it ready for anyone else, so there's no documentation at 
this point, but here's some sample code:
    
    
    import nimutils, strutils, options
      var
        encCtx: GcmCtx
        decCtx: GcmCtx
        nonce:  string
        ct:     string
        pt    = "This is a test between disco and death"
        key   = "0123456789abcdef"
      gcmInitEncrypt(encCtx, key)
      gcmInitDecrypt(decCtx, key)
      
      echo "Initial pt: ", pt
      
      for i in 1 .. 10:
        ct        = encCtx.gcmEncrypt(pt)
        nonce = encCtx.gcmGetNonce()
        pt        = decCtx.gcmDecrypt(ct, nonce).get("<error>")
        
        echo "Nonce: ", nonce.hex()
        echo "CT: "
        echo ct.strDump()
        echo "Decrypted: ", pt
    
    
    Run

Alternately, I believe someone in the community maintains a good wrapping of 
libSodium; the SecretBox abstraction there. 

Reply via email to