tinyssh icon indicating copy to clipboard operation
tinyssh copied to clipboard

How to build a smaller tinysshd?

Open philanc opened this issue 6 years ago • 12 comments

My objective is to build a tinysshd (static build, with musl libc) as small as possible. Performance is not an issue. The ssh client would be a recent ssh from OpenSSH.

  1. Is it possible to easily build tinysshd with only ed25519 / chacha-poly1305 crypto? (ie. no nistp256ecdsa, no aes)

  2. I have seen an old HackerNews post mentioning TweetNacl ( https://news.ycombinator.com/item?id=7727738 ) -- Is it still possible to build tinysshd with tweetnacl?

Thanks for Tinysshd!

Phil

philanc avatar Nov 29 '18 02:11 philanc

Hello,

  1. branch nooldcrypto https://github.com/janmojzis/tinyssh/tree/nooldcrypto ... and using -Os unstriped binary is 1.6x smaller (compiled on my laptop)

  2. TweetNacl was used in early version of tinyssh and there is few problems

  • TweetNacl doesn't have crypto_stream_chacha20, crypto_hash_sha256
  • TweetNacl has very,very,very slow crypto_onetimeauth_poly1305

janmojzis avatar Dec 06 '18 05:12 janmojzis

or branch noprecomputedtables https://github.com/janmojzis/tinyssh/tree/noprecomputedtables unstriped binary is ~1.67x smaller (compiled on my laptop) but with slowdown penalty, crypto_sign_ed25519_sign is ~1.55x slower

janmojzis avatar Dec 06 '18 08:12 janmojzis

using both optimizations: removing aes/nistp256/hmacsha256 + no precomputed tables the binary can be smaller ~1.9x

janmojzis avatar Dec 06 '18 08:12 janmojzis

https://github.com/janmojzis/tinyssh/tree/noprecomputedtables merged into main

janmojzis avatar Dec 06 '18 13:12 janmojzis

Thanks a lot!

I built the old master, and the last noprecomputedtables + nooldcrypto, both with -Os, static, with musl libc, stripped (on linux x86-64, built with make-tinysshcc.sh): old tinysshd: 306,272 bytes new tinysshd: 141,728 bytes

On regular servers, people will keep using OpenSSH anyway, but for administering tiny servers or IoT platforms where raw performance is usually not an issue, this last tinysshd, with only one set of modern crypto and no pre-computed tables could be very useful.

I would suggest to offer this last configuration at least as a build option in the master branch.

Thanks again!

philanc avatar Dec 06 '18 21:12 philanc

It might be worth trying to try and use LTO if size matters.

Avamander avatar Dec 14 '18 18:12 Avamander

It might be worth trying to try and use LTO if size matters.

My previous lowest size was 141,728 stripped, built with make-tinysshcc.sh and conf-cc =

/opt/musl/bin/musl-gcc -static -Os -fomit-frame-pointer -funroll-loops

To build with LTO, I had to change all instances of 'ar' in make-tinysshcc.sh into 'gcc-ar', so that ar knows about some lto plugin(s). Then I built with conf-cc =

/opt/musl/bin/musl-gcc -static -Os -fomit-frame-pointer -flto

Now tinysshd stripped is 129,352 bytes. 12KB less. Not bad!

Thanks for the hint.

philanc avatar Dec 14 '18 20:12 philanc

branch nooldcrypto also merged into main

janmojzis avatar Dec 24 '18 12:12 janmojzis

You can make it even smaller with upx

-rwxr-xr-x 1 root root 122184 Sep 5 2019 tinysshd* -rwxr-xr-x 1 root root 51368 Mar 22 10:38 tinysshd.upx* upx on tinysshd -rwxr-xr-x 1 root root 46872 Mar 22 10:38 tinysshd.upx.lzma* upx --lzma on tinysshd

not sure how small you could go with using tinysshd.c and #!/usr/bin/tcc -run

alexmyczko avatar Mar 22 '21 09:03 alexmyczko

You can make it even smaller with upx

Nice idea, thanks! - It is interesting when storage space is an issue. Of course it doesn't help (and makes things worse) when RAM space is the issue.

not sure how small you could go with using tinysshd.c and #!/usr/bin/tcc -run

An intriguing option! I will check how it works.

philanc avatar Mar 22 '21 18:03 philanc

UCL has been designed to be simple enough that a decompressor can be implemented in just a few hundred bytes of code. UCL requires no additional memory to be allocated for decompression, a considerable advantage that means that a UPX packed executable usually requires no additional memory.

from: https://en.wikipedia.org/wiki/UPX?wprov=sfti1

alexmyczko avatar Mar 22 '21 18:03 alexmyczko

UCL requires no additional memory to be allocated for decompression, a considerable advantage that means that a UPX packed executable usually requires no additional memory.

Great! I built upx and tried it on the current tinysshd: tinysshd 153,960 bytes (static build, with musl libc, stripped) tinysshd.upx 72,036 bytes (same, compressed with upx)

Yay! Thanks for the suggestion.

Is there a simple way to build without the PQ crypto?

philanc avatar Mar 22 '21 22:03 philanc