aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarLibravatar william <william@25thandclement.com> 2015-02-25 14:58:33 -0800
committerLibravatarLibravatar william <william@25thandclement.com> 2015-02-25 14:58:33 -0800
commit7dce9c391259f1b72f949f73ac1604d6fcb79fdd (patch)
tree5f60be305aab04077da5fbcd8e3b4ee0e46d9ffd
parent1476267d26c9b0cac8818bf7a74696d48505b79d (diff)
downloadluaossl-7dce9c391259f1b72f949f73ac1604d6fcb79fdd.tar.gz
luaossl-7dce9c391259f1b72f949f73ac1604d6fcb79fdd.tar.bz2
luaossl-7dce9c391259f1b72f949f73ac1604d6fcb79fdd.zip
document des.set_odd_parity and add example
-rw-r--r--doc/luaossl.pdfbin281822 -> 282537 bytes
-rw-r--r--doc/luaossl.tex10
-rwxr-xr-xexamples/lm.hash71
3 files changed, 79 insertions, 2 deletions
diff --git a/doc/luaossl.pdf b/doc/luaossl.pdf
index 8078e4b..4237910 100644
--- a/doc/luaossl.pdf
+++ b/doc/luaossl.pdf
Binary files differ
diff --git a/doc/luaossl.tex b/doc/luaossl.tex
index 239c98a..2302e3a 100644
--- a/doc/luaossl.tex
+++ b/doc/luaossl.tex
@@ -985,11 +985,17 @@ The routine operates internally on 64-bit unsigned integers.\footnote{Actually,
\begin{Module}{openssl.des}
-Binds OpenSSL's DES interfaces. These bindings are incomplete. No modern protocol would ever need to use these directly. However, legacy protocols like Windows NTLM authentication require some of these low-level interfaces.
+Binds OpenSSL's DES interfaces. These bindings are incomplete. No modern protocol would ever need to use these directly. However, legacy protocols like Windows LAN Manager authentication require some of these low-level interfaces.
\subsubsection[\fn{des.string\_to\_key}]{\fn{des.string\_to\_key($password$)}}
-Converts an arbitrary length string, $password$, to a DES key. Returns an 8-byte string.
+Converts an arbitrary length string, $password$, to a DES key using DES\_string\_to\_key. Returns an 8-byte string.
+
+Note that OpenSSL's DES\_string\_to\_key is not compatible with Windows LAN Manager hashing scheme. Use \fn{des.set\_odd\_parity} instead. See examples/lm.hash.
+
+\subsubsection[\fn{des.set\_odd\_parity}]{\fn{des.set\_odd\_parity($key$)}}
+
+Applies DES\_set\_odd\_parity to the string $key$. Only the first 8 bytes of $key$ are processed. Returns an 8-byte string.
\end{Module}
diff --git a/examples/lm.hash b/examples/lm.hash
new file mode 100755
index 0000000..4d8157c
--- /dev/null
+++ b/examples/lm.hash
@@ -0,0 +1,71 @@
+#!/bin/sh
+_=[[
+ : ${LUA:=$(command -v lua-5.2)}
+ : ${LUA:=$(command -v lua5.2)}
+ : ${LUA:=$(command -v lua-52)}
+ : ${LUA:=$(command -v lua52)}
+ : ${LUA:=$(command -v luajit)}
+ : ${LUA:=$(command -v lua)}
+
+ exec ${LUA} "$0" "$@"
+]]
+
+local des = require"openssl.des"
+local cipher = require"openssl.cipher"
+local bit32 = require"bit32"
+
+local function lm_encrypt(key)
+ return cipher.new"DES-ECB":encrypt(key, nil, false):final"KGS!@#$%"
+end -- lm_encrypt
+
+local lshift = bit32.lshift
+local band = bit32.band
+local rshift = bit32.rshift
+local bor = bit32.bor
+
+local function lm_string_to_key(s)
+ local s0, s1, s2, s3, s4, s5, s6 = string.byte(s, 1, 7)
+ local k0, k1, k2, k3, k4, k5, k6, k7
+
+ s0 = s0 or 0
+ s1 = s1 or 0
+ s2 = s2 or 0
+ s3 = s3 or 0
+ s4 = s4 or 0
+ s5 = s5 or 0
+ s6 = s6 or 0
+
+ k0 = s0
+ k1 = bor(band(lshift(s0, 7), 255), rshift(s1, 1))
+ k2 = bor(band(lshift(s1, 6), 255), rshift(s2, 2))
+ k3 = bor(band(lshift(s2, 5), 255), rshift(s3, 3))
+ k4 = bor(band(lshift(s3, 4), 255), rshift(s4, 4))
+ k5 = bor(band(lshift(s4, 3), 255), rshift(s5, 5))
+ k6 = bor(band(lshift(s5, 2), 255), rshift(s6, 6))
+ k7 = band(lshift(s6, 1), 255)
+
+ return des.set_odd_parity(string.char(k0, k1, k2, k3, k4, k5, k6, k7))
+end -- lm_string_to_key
+
+local function lm_hash(pass)
+ pass = string.upper(pass)
+
+ if #pass < 14 then
+ pass = pass .. string.rep(string.char(0), 14 - #pass)
+ end
+
+ local key1 = lm_string_to_key(string.sub(pass, 1, 7))
+ local key2 = lm_string_to_key(string.sub(pass, 8, 14))
+
+ return lm_encrypt(key1) .. lm_encrypt(key2)
+end -- lm_hash
+
+local function tohex(s)
+ return (string.gsub(s, ".", function (c)
+ return string.format("%.2x", string.byte(c))
+ end))
+end -- tohex
+
+local pass = ... or "passphrase"
+
+print(pass, tohex(lm_hash(... or "passphrase")))