dhke,
chacha20,
poly1305,
+ chacha20_poly1305,
rsa_keygen,
rsa_import,
rsa_padding_oaep,
rsa_padding_pss,
- byteStringToHexString
+ byteStringToHexString,
+ fromNumberFixedSize
)
where
import System.IO as IO
import Data.ByteString.Internal
import Data.Word
import Data.ByteString.Unsafe
-import Control.DeepSeq
import Control.Monad
import qualified Data.ByteString.Internal as BI
import qualified Foreign.Marshal.Utils as MU
c_rsa_keygen (fromIntegral n) pubKeyPtr prvKeyPtr
pubKey <- BI.create keySize (\ptr -> MU.copyBytes ptr (castPtr pubKeyPtr) keySize)
prvKey <- BI.create keySize (\ptr -> MU.copyBytes ptr (castPtr prvKeyPtr) keySize)
- fn pubKey prvKey
+ fn prvKey pubKey
rsa_free pubKey
rsa_free prvKey
rsa_free :: ByteString -> IO()
rsa_free blob = useAsCString blob $ \ptr -> c_rsa_free (castPtr ptr)
-dhke :: (ByteString, ByteString) -> IO (ByteString)
+dhke :: [ByteString] -> IO (ByteString)
dhke v = do
c_modSize <- c_dhke_modsize
let modSize = fromIntegral c_modSize
- if ((BS.length(fst v) + BS.length(snd v)) == 0) then do
+ if Prelude.length v == 0 then do
secretPtr <- c_dhke nullPtr nullPtr
bsPtr <- BI.create modSize (\ptr -> MU.copyBytes ptr (castPtr secretPtr) modSize)
c_free secretPtr
return bsPtr
- else if (BS.length(snd v) == 0) then do
- useAsCString (fst v) $ \secretPtr -> do
+ else if Prelude.length v == 1 then do
+ useAsCString (v !! 0) $ \secretPtr -> do
sharePtr <- c_dhke (castPtr secretPtr) nullPtr
bsPtr <- BI.create modSize (\ptr -> MU.copyBytes ptr (castPtr sharePtr) modSize)
c_free sharePtr
return bsPtr
- else if (BS.length(snd v) > 0) then do
- useAsCString (fst v) $ \secretPtr -> do
- useAsCString (snd v) $ \sharePtr -> do
+ else if Prelude.length v == 2 then do
+ useAsCString (v !! 0) $ \secretPtr -> do
+ useAsCString (v !! 1) $ \sharePtr -> do
keyPtr <- c_dhke (castPtr secretPtr) (castPtr sharePtr)
bsPtr <- BI.create modSize (\ptr -> MU.copyBytes ptr (castPtr keyPtr) modSize)
c_free keyPtr
return bsPtr
else return BS.empty
-sha256 :: ByteString -> IO (String)
+sha256 :: ByteString -> IO (ByteString)
sha256 ptBS = do
let ptSize :: Word32
ptSize = fromIntegral (BS.length ptBS)
hPtr <- c_sha256 (castPtr ptPtr) (fromIntegral ptSize)
hBS <- BI.create 32 (\ptr -> MU.copyBytes ptr (castPtr hPtr) 32)
c_free hPtr
- return (byteStringToHexString hBS)
+ return hBS
hmac :: Int -> ByteString -> ByteString -> IO (ByteString)
hmac h k m = do
c_free rPtr
return r
-chacha20 :: ByteString -> ByteString -> Int -> Int -> IO (ByteString)
+chacha20 :: ByteString -> Integer -> Int -> Int -> IO (ByteString)
chacha20 key nonce block count = do
- if (BS.length key) /= 32 || (BS.length nonce) /= 12 || block < 0 || count < 0 then
+ let nonceBS :: BS.ByteString
+ nonceBS = fromNumberFixedSize nonce 12
+ if (BS.length key) /= 32 || (BS.length nonceBS) /= 12 || block < 0 || count < 0 then
return BS.empty
else
useAsCString key $ \keyPtr -> do
- useAsCString nonce $ \noncePtr -> do
+ useAsCString nonceBS $ \noncePtr -> do
rPtr <- c_chacha20 (castPtr keyPtr) (castPtr noncePtr) (fromIntegral block) (fromIntegral count)
r <- BI.create count (\ptr -> MU.copyBytes ptr (castPtr rPtr) count)
c_free rPtr
c_free hPtr
return h
-chacha20_poly1305 :: ByteString -> ByteString -> ByteString -> IO (ByteString)
+chacha20_poly1305 :: ByteString -> Integer -> ByteString -> IO (ByteString)
chacha20_poly1305 key nonce ctext = do
- if (BS.length key) /= 32 || (BS.length nonce) /= 12 then
+ let nonceBS :: BS.ByteString
+ nonceBS = fromNumberFixedSize nonce 12
+ if (BS.length key) /= 32 || (BS.length nonceBS) /= 12 then
return BS.empty
else
useAsCString key $ \keyPtr -> do
- useAsCString nonce $ \noncePtr -> do
+ useAsCString nonceBS $ \noncePtr -> do
useAsCString ctext $ \ctextPtr -> do
rPtr <- c_chacha20_poly1305 (castPtr keyPtr) (castPtr noncePtr) (castPtr ctextPtr) (fromIntegral (BS.length ctext))
r <- BI.create 16 (\ptr -> MU.copyBytes ptr (castPtr rPtr) 16)
c_free rPtr
return r
-
byteToHexString :: Word8 -> String
byteToHexString b = do
case (div b 16) of
14 -> "e"
15 -> "f"
_ -> "0"
-
byteStringToByteList :: ByteString -> [Word8]
byteStringToByteList b = BS.unpack b
byteStringToInteger :: ByteString -> Integer
byteStringToInteger = foldl' (\acc byte -> acc * 256 + fromIntegral byte) 0
+
+fromNumberFixedSize :: Integer -> Int -> BS.ByteString
+fromNumberFixedSize n p = do
+ if n < 0 || p < 0 then BS.empty
+ else do
+ let fn :: Integer -> [Word8] -> [Word8]
+ fn x r = if x == 0 then r else fn (div x 256) ([fromIntegral (mod x 256)] ++ r)
+ pd :: [Word8] -> [Word8]
+ pd x = if (Prelude.length x) < p then pd ([0] ++ x) else x
+ rt = pd (fn n [])
+ BS.pack $ if (Prelude.length rt) > p then Prelude.drop ((Prelude.length rt) - p) rt else rt
\ No newline at end of file
--- /dev/null
+#ifndef __PAM__
+#define __PAM__
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <security/pam_appl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+
+static int pam_conv_func(int num_msg, const struct pam_message **msg,
+ struct pam_response **resp, void *appdata_ptr) {
+ *resp = (struct pam_response *)malloc(num_msg * sizeof(struct pam_response));
+ for (int i = 0; i < num_msg; i++) {
+ resp[i]->resp = strdup((char *)appdata_ptr);
+ resp[i]->resp_retcode = 0;
+ }
+ return PAM_SUCCESS;
+}
+
+uint8_t pam(uint8_t* username, uint8_t* password)
+{
+ struct passwd *p;
+ p = getpwuid(geteuid());
+ if (p == NULL) return 0;
+ if (username == NULL) username = p->pw_name;
+
+ pam_handle_t *pamh = NULL;
+ struct pam_conv conv = { pam_conv_func, NULL };
+
+ conv.appdata_ptr = (void*)password;
+
+ int retval = pam_start("login", username, &conv, &pamh);
+
+ if (retval == PAM_SUCCESS)
+ retval = pam_authenticate(pamh, 0);
+
+ if (pamh) pam_end(pamh, retval);
+ return retval == PAM_SUCCESS;
+}
+#endif
\ No newline at end of file