GithubHelp home page GithubHelp logo

haskell-cryptography / libsodium-bindings Goto Github PK

View Code? Open in Web Editor NEW
31.0 5.0 13.0 4.51 MB

Bindings to libsodium for Haskell

License: BSD 3-Clause "New" or "Revised" License

Makefile 0.28% Haskell 99.57% Shell 0.07% Nix 0.08%
haskell cryptography libsodium

libsodium-bindings's Introduction

Sodium Bindings made with Haskell

The Haskell Cryptography Group presents its suite of libsodium packages:

Package Status
sel sel-badge
libsodium‑bindings lb-badge

Comparison with other libraries

Name Nature Dependencies GHC Support
libsodium‑bindings Low-level FFI bindings base Starts with 8.10.7
sel High-level Haskell interface base, base16, bytestring, text text-display, libsodium‑bindings Starts with 9.2.8
saltine Both FFI bindings and high-level interface base, bytestring deepseq, text, hashable, profunctors Starts with 8.0.2
libsodium Low-level FFI bindings base 8.6.5 to 8.10.1
crypto‑sodium High-level Haskell interface base, bytestring, random, cereal, libsodium, memory, Unclear
Name FFI Convention Library Discovery
libsodium‑bindings Recommended capi convention pkg-config, homebrew (macOS-only), cabal‑native
saltine Legacy ccall convention pkg-config, cabal-native
libsodium Legacy ccall convention pkg-config

libsodium-bindings's People

Contributors

a-02 avatar blackheaven avatar dependabot[bot] avatar dpwiz avatar kleidukos avatar kozross avatar mangoiv avatar mergify[bot] avatar raoulhc avatar s-and-witch avatar teofilc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

libsodium-bindings's Issues

Module hierarchy for symmetric and asymmetric cryptography

I'm not super certain what I would like this module hierarchy to look like. I see several options for the symmetric cryptography:

  • Sel.SecretKey.AuthenticatedEncryption
  • Sel.SecretKey.AuthenticatedStream
  • Sel.SecretKey.Authentication

or

  • Sel.SecretBox
  • Sel.SecretStream
  • Sel.Auth

For asymmetric cryptography the names given by libsodium would be

  • Sel.PublicKey.AuthenticatedEncryption
  • Sel.PublicKey.Signature
  • Sel.PublicKey.SealedBox

or

  • Sel.Box
  • Sel.Sign
  • Sel.Seal

@kozross @divarvel @a-02 @axman6 what do you think?

Create an index in LibSodium.Bindings

Feedback from @monadplus:

Libsodium has a lot to offer, but hard to discover.
Currently, a user has to open each individual module documentation to understand the capabilities of this library
which isn't the best user experience and most people will skip because of this until they are already knowledge with libsodium from C. Here are a couple of suggestions on how to ammend this:

  • A top-level module with the same name as the package itself i.e. LibSodium.Bindings with a listing and a brief description of each submodule.
  • If you don't want a top-level module, you could add this info to the README.

We're going with solution 1: An index in the Haddocks.

`passwordHashToText` is broken

passwordHashToText doesn't work because there's no guarantee that the hash generated is valid UTF-8.

It should either be removed or encoded in Base16 as a lot of the hashes in the rest of sel seem to do, though in the latter case it should probably be renamed passwordHashToHexText.

SHA-384 bindings

From what I understand, SHA-384 is a truncated output of SHA-512.

@jmcardon any opinion on this? Should we wrap libsodium or look for a native backend?

CI badges link to the wrong url

Badges should be of the form sel-badge i.e. [![sel-badge]][sel-ci] where

[sel-badge]: https://github.com/haskell-cryptography/libsodium-bindings/actions/workflows/sel.yml/badge.svg
[sel-ci]: https://github.com/haskell-cryptography/libsodium-bindings/actions/workflows/sel.yml?query=branch%3Amain

Suggestions wrt `MultiPart`

It is said, that it would be bad if the Multipart escapes its scope, so perhaps we can do the skolem trick on it. I don't know exactly whether this is sound, it's merely an idea and perhaps it's non-sense:

data Multipart s = Multipart

withMultipart
  :: MonadIO m
  => (forall s. Multipart s -> m a)
  -> m a
withMultipart k = k Multipart

escapeMultiPart :: IORef (Multipart s) -> IO ()
escapeMultiPart ref = withMultipart (\part ->  writeIORef ref part)

Fails to build on mac using `libsodium-1.0.19` via homebrew

Currently libsodium-bindings won't build on mac when using homebrew because homebrew recently updated the libsodium recipe and now only carries libsodium-1.0.19.

This fails on any combination of the flags use-pkg-config and homebrew-libsodium.

Using use-pkg-config with or without homebrew-libsodium:

libsodium-bindings           > Error: Cabal-simple_6HauvNHV_3.8.1.0_ghc-9.4.7: The pkg-config package                                                
libsodium-bindings           > 'libsodium' version ==1.0.18 is required but the version installed on the                                             
libsodium-bindings           > system is version 1.0.19                                                                                              
libsodium-bindings           >       

Using no flags or homebrew-libsodium:

libsodium-bindings           > Error: Cabal-simple_6HauvNHV_3.8.1.0_ghc-9.4.7: Missing dependency on a                                    
libsodium-bindings           > foreign library:                                                                                           
libsodium-bindings           > * Missing (or bad) C library: sodium                                                                       
libsodium-bindings           > This problem can usually be solved by installing the system package that                                   
libsodium-bindings           > provides this library (you may need the "-dev" version). If the library is                                 
libsodium-bindings           > already installed but in a non-standard location then you can use the flags                                
libsodium-bindings           > --extra-include-dirs= and --extra-lib-dirs= to specify where it is.If the                                  
libsodium-bindings           > library file does exist, it may contain errors that are caught by the C                                    
libsodium-bindings           > compiler at the preprocessing stage. In this case you can re-run configure                                 
libsodium-bindings           > with the verbosity flag -v3 to see the error messages.                                                     
libsodium-bindings           >                                                            

I've tested relaxing the libsodium dependency in libsodium-bindings.cabal: pkgconfig-depends: libsodium ==1.0.18 || ==1.0.19

That seems to build, though I haven't checked if any breaking changes have been introduced as a result.

SecretBox bindings

It would be nice if this package exposed bindings to libsodium's secretbox api.

As far as I can tell that api could be used to implement the cryptography for clientsession (though I'm not entirely sure about this), which currently depends on deprecated cryptography libraries, but is used by a bunch of other packages, eg, yesod, snap, git-annex, etc (https://packdeps.haskellers.com/reverse/clientsession)

If this sounds in scope for this package, I'd be happy to help add bindings for this api

LibSodium.Bindings.AEAD documentation

In LibSodium.Bindings.AEAD, it may be a good idea to replace in the documentation the constants

  • crypto_aead_xchacha20poly1305_ietf_KEYBYTES
  • crypto_aead_xchacha20poly1305_ietf_NPUBBYTES
  • crypto_aead_xchacha20poly1305_ietf_ABYTES

By :

  • cryptoAEADXChaCha20Poly1305IETFKeyBytes
  • cryptoAEADXChaCha20Polt1305IETFPubBytes
  • cryptoAEADXChaCha20Poly1305IETFABytes

Using c2hs to generate bindings

On the advice of @divarvel and after discussing with @angerman, I would like to explore the idea of using c2hs for the generation of bindings, with the important distinction that we ship the generated Haskell code in the sdist when uploading the package, as not to impose any burden on the downstream users at build-time.

Unable to re-use nix-based build

I'm trying to add nix build support on a project which depends on sel, but I fail to make GHC detect sel:

@nix { "action": "setPhase", "phase": "setupCompilerEnvironmentPhase" }
setupCompilerEnvironmentPhase
Build with /nix/store/psds2pz1qhlr4z8qcahqii6kq1xsawb8-ghc-9.4.8.
@nix { "action": "setPhase", "phase": "unpackPhase" }
unpacking sources
unpacking source archive /nix/store/sbin4qzj03wn252n0qibwn6jj9p1xnrc-bvh2s0sx28rfp0gzysj4p5fwzxzz0djx-source
source root is bvh2s0sx28rfp0gzysj4p5fwzxzz0djx-source
@nix { "action": "setPhase", "phase": "patchPhase" }
patching sources
@nix { "action": "setPhase", "phase": "compileBuildDriverPhase" }
compileBuildDriverPhase
setupCompileFlags: -package-db=/build/tmp.2qEJsW8rMl/setup-package.conf.d -j16 +RTS -A64M -RTS -threaded -rtsopts
[1 of 2] Compiling Main             ( /nix/store/4mdp8nhyfddh7bllbi7xszz7k9955n79-Setup.hs, /build/tmp.2qEJsW8rMl/Main.o )
[2 of 2] Linking Setup
@nix { "action": "setPhase", "phase": "updateAutotoolsGnuConfigScriptsPhase" }
updateAutotoolsGnuConfigScriptsPhase
@nix { "action": "setPhase", "phase": "configurePhase" }
configuring
configureFlags: --verbose --prefix=/nix/store/bypr7jw18cg0la1mq0wb3wnhiq8rb1sq-one-time-password-3.0.0.0 --libdir=$prefix/lib/$compiler --libsubdir=$abi/$libname --docdir=/nix/store/pq6lxf7hii5ghjgc9fayl5cpln5c6w1k-one-time-password-3.0.0.0-doc/share/doc/one-time-password-3.0.0.0 --with-gcc=gcc --package-db=/build/tmp.2qEJsW8rMl/package.conf.d --ghc-options=-j16 +RTS -A64M -RTS --disable-split-objs --enable-library-profiling --profiling-detail=exported-functions --disable-profiling --enable-shared --disable-coverage --enable-static --disable-executable-dynamic --enable-tests --disable-benchmarks --enable-library-vanilla --disable-library-for-ghci --ghc-option=-split-sections --ghc-options=-haddock --extra-lib-dirs=/nix/store/5i51nfixxx3p3gshkfsjj4bzp7wajwxz-ncurses-6.4/lib --extra-lib-dirs=/nix/store/9kd4bc8fpclpvf1vdwlbila71svyb6w1-libffi-3.4.4/lib --extra-lib-dirs=/nix/store/s3s7gv33p88kzbgki2bprg2a1nc7jnf8-gmp-with-cxx-6.3.0/lib --extra-lib-dirs=/nix/store/84qfr9nk7c7yh1ah3p9nvlq9d8y3h0rx-sel-0.0.1.0/lib --extra-lib-dirs=/nix/store/bvavjfn6m8x5y5i7a8qf85knknc4jrbp-base16-1.0/lib --extra-lib-dirs=/nix/store/gpmsy9p2fffmpbfc6x6xz12w9cn27ll3-primitive-0.8.0.0/lib --extra-lib-dirs=/nix/store/s6wr8nm2cxkz25lawf51aw8dv2kdq26l-text-short-0.1.5/lib --extra-lib-dirs=/nix/store/mqi0rc4qb5sjs78fbbgwqpcna1m71hwj-hashable-1.4.3.0/lib --extra-lib-dirs=/nix/store/5w8sb907h7rid9amykak5d8kjf3za4gw-libsodium-bindings-0.0.1.0/lib --extra-lib-dirs=/nix/store/zriy44k8iya3j45lxhfm8zf4s5q2s7zg-text-display-0.0.5.1/lib
Using Parsec parser
Configuring one-time-password-3.0.0.0...
CallStack (from HasCallStack):
  withMetadata, called at libraries/Cabal/Cabal/src/Distribution/Simple/Utils.hs:370:14 in Cabal-3.8.1.0:Distribution.Simple.Utils
Error: Setup: Encountered missing or private dependencies:
sel

PS: it seems that freezing GHC version causes the issue

Add Scrypt interface to Sel

We should have the Scrypt bindings from libsodium in Sel.Scrypt. Take inspiration from Sel.Hashing.Password.

Documentation coherence

Reading throught the documentation, a lot of See: [C function name] don't follow the same format (and in one module, namely LibSodium.Bindings.CryptoAuth, they are missing). The proposed changes are following, based on unifying the use of parentheses after a C function name.

  • LibSodium.Bindings.AEAD
    • cryptoAEADXChaCha20Poly1305IETFEncrypt: crypto_aead_xchacha20poly1305_ietf_encrypt()
    • cryptoAEADXChaCha20Poly1305IETFDecrypt: crypto_aead_xchacha20poly1305_ietf_decrypt()
    • cryptoAEADXChaCha20Poly1305IETFEncryptDetached: crypto_aead_xchacha20poly1305_ietf_encrypt_detached()
    • cryptoAEADXChaCha20Poly1305IETFDecryptDetached: crypto_aead_xchacha20poly1305_ietf_decrypt_detached()
  • LibSodium.Bindings.Comparison
    • sodiumMemcmp: sodium_memcmp()
    • sodiumIsZero: sodium_is_zero()
  • LibSodium.Bindings.CryptoAuth. Here the functions are not documented, only "See: Secret Key Authentification". Changes suggested :
    • cryptoAuth: crypto_auth()
    • cryptoAuthVerify: crypto_auth_verify()
    • cryptoAuthKeygen: crypto_auth_keygen()
  • LibSodium.Bindings.CryptoBox
    • cryptoBoxKeyPair: crypto_box_keypair()
    • cryptoBoxSeedKeyPair: crypto_box_seed_keypair()
    • cryptoBoxEasy: crypto_box_easy()
    • cryptoBoxOpenEasy: crypto_box_open_easy()
    • cryptoBoxDetached: crypto_box_detached()
    • cryptoBoxOpenDetached: crypto_box_open_detached()
    • cryptoBoxBeforeNM: crypto_box_beforenm()
    • cryptoBoxEasyAfterNM: crypto_box_easy_afternm()
    • Notice here that for the following three the same reference is used although the three functions are differents. The fixes are in parentheses.
      • cryptoBoxOpenEasyAfterNM: crypto_box_open_easy_afternm()
      • cryptoBoxDetachedAfterNM: crypto_box_open_easy_afternm() (crypto_box_detached_afternm())
      • cryptoBoxOpenDetachedAfterNM: crypto_box_open_easy_afternm() (crypto_box_open_detached_afternm())
  • LibSodium.Bindings.CryptoSign
    • cryptoSignInit: crypto_sign_init()
    • cryptoSignUpdate: crypto_sign_update()
    • cryptoSignFinalCreate: crypto_sign_final_create()
    • cryptoSignFinalVerify: crypto_sign_final_verify()
    • cryptoSignED25519SkToSeed: crypto_sign_ed25519_sk_to_seed()
    • cryptoSignED25519SkToPk: crypto_sign_ed25519_sk_to_pk()
  • LibSodium.Bindings.Main
    • sodiumInit : sodium_init()
  • LibSodium.Bindings.Random
    • randombytesRandom: randombytes_random()
    • randombytesUniform: randombytes_uniform()
    • randombytesBuf: randombytes_buf()
  • LibSodium.Bindings.SecretStream
    • cryptoSecretStreamXChaCha20Poly1305KeyGen: crypto_secretstream_xchacha20poly1305_keygen()
    • cryptoSecretStreamXChaCha20Poly1305InitPush: crypto_secretstream_xchacha20poly1305_init_push()
    • cryptoSecretStreamXChaCha20Poly1305Push: crypto_secretstream_xchacha20poly1305_push
    • cryptoSecretStreamXChaCha20Poly1305InitPull: crypto_secretstream_xchacha20poly1305_init_pull()
    • cryptoSecretStreamXChaCha20Poly1305Pull: crypto_secretstream_xchacha20poly1305_pull()
    • cryptoSecretStreamXChaCha20Poly1305Rekey: crypto_secretstream_xchacha20poly1305_rekey()
  • LibSodium.Bindings.XChaCha20
    • cryptoStreamXChaCha20: crypto_stream_xchacha20()
    • cryptoStreamXChaCha20Xor: crypto_stream_xchacha20_xor()
    • cryptoStreamXChaCha20XorIC: crypto_stream_xchacha20_xor_ic()
    • cryptoStreamXChaCha20Keygen: cryptoStreamXChaCha20Keygen()

capi incompatibilities could cause us issues

Based on this GHC issue here, we may have trouble if we enforce capi everywhere. In fact, I've already run into problems with it. Twice.

While in my linked cases, it's not exactly a problem, as having bindings to those helpers isn't strictly necessary, this may cause us trouble in the future with things we do care about. What should our policy be in this case? I can see two solutions:

  • Use ccall for the problem cases; or
  • Wait for GHC to fix the issue upstream, or even commit some time ourselves to fix it.

The first option is the one I prefer, but I'm not sure if it will be problematic or not. The second option is better ecosystemically-speaking, but will take much longer, and essentially limit us only to those compiler version(s) that will have this fix backported to them.

@Kleidukos - what are your thoughts on this?

Zeroing ForeignPtrs on deallocation

Given all the warnings and "[REDACTED]" instances I was surprised that there are no memory clean-up for those objects.

Perhaps there should be an mallocForeignPtrBytes wrapper that automatically attaches addForeignPtrFinalizer with fillBytes or sodium_memzero().

OTOH, when you import your secrets from a ByteString or hex, it's already a game over in this department 🤷‍♀️

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.