Friday, April 8, 2016

Basic Communications Security - Part 1

I've recently been helping a friend get set up with GPG.  Also, I've been switching my password management over to pass.

Through this process, I have found GPG to be fairly straight forward, but it may be a bit daunting for some without prior crypto experience.  In this short series, I am going to cover basic setup of GPG for encryption and signing.  This keypair will consist of subkeys with an offline private master.  Once we have a working and secure GPG setup, I will move on to cover password management with pass, as well as GPG based authentication, and ultimately using hardware GPG tokens.

Hopefully this series will be useful to some.  As always, I welcome comments, questions, and corrections.

Part I - Key Generation

Note:  The example text was sourced from several different key operations on several different keys.  The key IDs and fingerprints in the example text may or may not correspond to valid and active keys.  My key can be retrieved from sks-keyservers, and it's ID is 86F22317.  Please use this key if you need to contact me.

For the sake of paranoia, I will be generating a master key on removable storage.  This key will be used to create subkeys for encryption, signing, and authentication, and it will be stored on removable storage in a safe.  To begin, you will need some clean removable media.  I am using OS X, so my media will be mounted at /Volumes/UNTITLED\ 1/.  Feel free to correct this path as appropriate for your environment.

First we will generate the key on the USB storage:

$ gpg --homedir /Volumes/UNTITLED\ 1/ --expert --gen-key

I use expert in this case to open up the option of setting custom capabilities for my keypair.  By default, GPG will generate a key that can sign and certify with a separate subkey that can encrypt.  I chose to create a master key that could only certify with subkeys that could encrypt and sign:

$ gpg --homedir /Volumes/UNTITLED\ 1/ --expert --gen-key
gpg: WARNING: unsafe permissions on homedir `/Volumes/UNTITLED\ 1/'
gpg (GnuPG) 1.4.20; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

gpg: keyring `/Volumes/UNTITLED\ 1/secring.gpg' created
gpg: keyring `/Volumes/UNTITLED\ 1/pubring.gpg' created
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
Your selection? 8

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? e

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 4y
Key expires at Tue Apr  7 11:05:27 2020 PDT
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) "

Real name: Peter H. Ezetta
Email address: protocall7@sdf.org
Comment:
You selected this USER-ID:
    "Peter H. Ezetta "

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
.................+++++
.+++++
gpg: /Volumes/UNTITLED\ 1/trustdb.gpg: trustdb created
gpg: key 86F22317 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2020-04-04
pub   4096R/86F22317 2016-04-08 [expires: 2020-04-07]
      Key fingerprint = E1D3 330D 0107 8360 5417  C337 33D5 14D6 86F2 2317
uid                  Peter H. Ezetta

At this point, I have generated a new certify only key pair that exists only on the USB stick.  Now I will edit the key to add UIDs and subkeys for encryption and signing:

$ gpg --homedir /Volumes/UNTITLED\ 1 --edit-key protocall7@sdf.org
gpg: WARNING: unsafe permissions on homedir `/Volumes/UNTITLED\ 1'
gpg (GnuPG) 1.4.20; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

pub  4096R/DDC547B9  created: 2016-04-08  expires: 2020-04-07  usage: C
                     trust: ultimate      validity: ultimate
[ultimate] (1). Peter H. Ezetta

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Peter H. Ezetta "
4096-bit RSA key, ID DDC547B9, created 2016-04-08

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
Your selection? 6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 1y
Key expires at Sat Apr  8 11:12:15 2017 PDT
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
............+++++
.........................+++++

pub  4096R/DDC547B9  created: 2016-04-08  expires: 2020-04-07  usage: C
                     trust: ultimate      validity: ultimate
sub  4096R/3BCD5DA0  created: 2016-04-08  expires: 2017-04-08  usage: E
[ultimate] (1). Peter H. Ezetta

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Peter H. Ezetta "
4096-bit RSA key, ID DDC547B9, created 2016-04-08

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 1y
Key expires at Sat Apr  8 11:12:43 2017 PDT
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
......+++++
.............+++++

pub  4096R/DDC547B9  created: 2016-04-08  expires: 2020-04-07  usage: C
                     trust: ultimate      validity: ultimate
sub  4096R/3BCD5DA0  created: 2016-04-08  expires: 2017-04-08  usage: E
sub  4096R/A5FA0D33  created: 2016-04-08  expires: 2017-04-08  usage: S
[ultimate] (1). Peter H. Ezetta

gpg> adduid
Real name: Peter H. Ezetta
Email address: protocall7@gmail.com
Comment:
You selected this USER-ID:
    "Peter H. Ezetta "

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

You need a passphrase to unlock the secret key for
user: "Peter H. Ezetta "
4096-bit RSA key, ID DDC547B9, created 2016-04-08


pub  4096R/DDC547B9  created: 2016-04-08  expires: 2020-04-07  usage: C
                     trust: ultimate      validity: ultimate
sub  4096R/3BCD5DA0  created: 2016-04-08  expires: 2017-04-08  usage: E
sub  4096R/A5FA0D33  created: 2016-04-08  expires: 2017-04-08  usage: S
[ultimate] (1)  Peter H. Ezetta
[ unknown] (2). Peter H. Ezetta

gpg> save


Now that the key has been generated on the USB stick, I create a revocation certificate just in case the key is lost of compromised.  This certificate should be closely guarded, as it will render the key useless, however you should maintain more than one copy of it in case it is necessary to use it.  A paper copy is recommended.

gpg --output /Volumes/UNTITLED\ 1/86F22317-revocation.asc --home /Volumes/UNTITLED\ 1 --gen-revoke protocall7@sdf.org
gpg: WARNING: unsafe permissions on homedir `/Volumes/UNTITLED\ 1'

sec  4096R/DDC547B9 2016-04-08 Peter H. Ezetta

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
(Probably you want to select 1 here)
Your decision? 0
Enter an optional description; end it with an empty line:
> Revocation certificate generated at time of key creation.  If this certificate is in use, it is likely I have lost access to the secret key.
>
Reason for revocation: No reason specified
Revocation certificate generated at time of key creation.  If this certificate is in use, it is likely I have lost access to the secret key.
Is this okay? (y/N) y

You need a passphrase to unlock the secret key for
user: "Peter H. Ezetta "
4096-bit RSA key, ID DDC547B9, created 2016-04-08

ASCII armored output forced.
Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable.  But have some caution:  The print system of
your machine might store the data and make it available to others!


The revocation certificate and key-pair exist only on the USB stick.  At this point, we need to import the secret subkeys to the local machine (leaving the secret key on the USB stick for safe keeping).  This can be done by exporting the secret subkeys, then importing them without --homedir:

$ gpg --homedir /Volumes/UNTITLED\ 1 --export-secret-subkeys protocall7@sdf.org > /Volumes/UNTITLED\ 1/secretsubkeys.gpg
$ gpg --homedir /Volumes/UNTITLED\ 1 --export protocall7@sdf.org > /Volumes/UNTITLED\ 1/publickey.gpg
$ gpg --import /Volumes/UNTITLED\ 1/publickey.gpg
gpg: key DDC547B9: public key "Peter H. Ezetta " imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

$ gpg --import /Volumes/UNTITLED\ 1/secretsubkeys.gpg
gpg: key DDC547B9: secret key imported
gpg: key DDC547B9: "Peter H. Ezetta " not changed
gpg: Total number processed: 1
gpg:              unchanged: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1

$ gpg -K
/Users/peter.ezetta/.gnupg/secring.gpg
--------------------------------------

sec#  4096R/DDC547B9 2016-04-08 [expires: 2020-04-07]
uid                  Peter H. Ezetta
uid                  Peter H. Ezetta
ssb   4096R/3BCD5DA0 2016-04-08
ssb   4096R/A5FA0D33 2016-04-08


From this, we see that the local copy of GPG has our secret subkeys in it's ring, but the secret key itself is missing (this is evidenced by the # after 'sec').  With the subkeys in place, encryption and signing still work just fine, but if a key needs to be created, revoked, or signed, the USB stick will have to be mounted up and --homedir will need to be added to gpg to point into the backup copy.  For demonstration purposes, here is the secret key output using the USB stick.  Notice that the secret key is present on this one:

$ gpg --homedir /Volumes/UNTITLED\ 1 -K
gpg: WARNING: unsafe permissions on homedir `
/Volumes/UNTITLED\ 1'
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2020-04-07
/Volumes/UNTITLED\ 1/secring.gpg
----------------------
sec   4096R/DDC547B9 2016-04-08 [expires: 2020-04-07]
uid                  Peter H. Ezetta
uid                  Peter H. Ezetta
ssb   4096R/3BCD5DA0 2016-04-08
ssb   4096R/A5FA0D33 2016-04-08


In the next part of this series, I will discuss the web of trust and key signing, then introduce Pass, "the UNIX default password manager".  Pass is backed by GPG encryption to keep your passwords safe, so now that keys have been set up, we can start using it.

Interesting Reading:

The GNU Privacy Handbook
Into The Void - Creating a new key with subkeys
Debian Wiki - Subkeys

Tuesday, June 16, 2015

PZ80emu - The PZ80 Machine Emulator

While I was messing about with the PZ80 schematics, I realized that I really needed an environment where I could write and run test code for the ROM monitor before I went burning EEPROMs.  I searched around for a few days for a suitable machine emulator, but ran into severe bugs with those that I found that weren't tailor made as CP/M emulators.

While I was searching around, I came across the website of Marat Fayzullin, who wrote a fantastic HOWTO on writing computer emulators:

http://fms.komkon.org/EMUL8/HOWTO.html

The PZ80emu is far from complete, but so far is able to load ROMs compiled by z80asm on my Mac.  It executes them quite well from what I tell, as long as I don't use any of the instructions I haven't implemented yet.  I have also implemented a very basic NCurses interface, mostly because I've never coded with NCurses before and thought it would be fun.

The code is most definitely alpha, and is incomplete, but anyone interested in hacking on what I've got so far is more than welcome.  I will certainly keep the Git repository up to date as I hack on the code, and will gladly accept pull requests.

https://github.com/protoCall7/PZ80emu

Sunday, June 14, 2015

PZ80 - Taking Another Step Back

After re-designing the bus buffering on the Z80, the project kind of stalled for me.  I ordered some parts now and again, and tweaked the schematics, but didn't make a whole lot of progress.

Feeling that this was an unacceptable state of affairs, I decided to take a step backwards and simplify my circuit.  What I would up with was the Z80 being fed with power from my bench supply, the entire data bus pulled low with 1K resistors, a few pull-up/down resistors on the control lines, and the oscillator.  Once that was set up, I connected my handy-dandy OpenBench Logic Analyzer up to the first 7 bits of the address bus, and to the clock signal, and fired everything up:



Admittedly, it didn't look like that on the first shot, but after some troubleshooting, it turned out to be user error in the configuration of the logic analyzer, not in the board itself.

The pattern above is caused by the address bus doing a binary countup.  The Z80 instruction set has the NOP instruction as 0x00.  By pulling the entire data bus low and resetting the CPU, the machine will start at address 0x0000, read a "NOP" from the data bus, increment the counter to 0x0001, read another "NOP", and repeat.  Since the current address in the program counter is displayed in binary on the address bus, the logic analyzer displays the above pattern when the board runs.

As far as farther incarnations of the design, I have decided to temporarily build a "MK1" type design, utilizing 32k of ROM and 32k of RAM.  It will use an SIO and a MAX-232 for serial communication, and I would like to work on implementing an IDE interface using CF storage (but this might wait).  This design won't be adequate to run CP/M, but will give me a working platform to start developing the ROM monitor, which will be an integral part of boot loading CP/M in the MK2 design, which would integrate a memory bank switching scheme to swap the ROM out for a 32k RAM chip as a part of the CP/M load process.

I haven't yet decided whether to implement the Z80-CTC for interrupt control + Z80-SIO timing in the MK1 design, or just use another full can oscillator to give a fixed serial baud rate, but I will be going with one of those two methods.

In the mean time, I have been working on putting together a machine emulator in C, as I haven't found anything suitable to write and debug my ROM monitor with, but that's a subject for another post.

One last note, I finally decided on a name - The PZ80!

Friday, June 12, 2015

Commodore Build

A few months back, I ran across a post over at Hackaday telling the story of a Kickstarter trying to put the original C64 injection molds back into production making enclosures.

http://hackaday.com/2015/03/11/hackaday-retro-edition-a-new-commodore-64-case/

I never had the pleasure of owning a C64, but I always wanted to play around with one, especially with some of the MIDI sequencer software floating around.  I couldn't help myself, and decided to back the Kickstarter and get one of the enclosures.  After hearing a horror story about a factory fire from the Kickstarter update, I started to doubt that the enclosure would ever show up... Until today today, when I received a mysterious package containing...



I am still working on sourcing a board, but I have a line on several non-functional ones.  I'm hoping that with a couple bad boards, the original schematics, and some soldering iron time, that I can cobble together a working C64.  Having the enclosures sitting here certainly makes the project feel more likely to actually happen.  Stay tuned for more updates!

Wednesday, February 4, 2015

Z80 Computer - Bus Buffering Rev 1

The original draft (and parts order) of my Z80 machine had a buffering scheme largely borrowed from the ZAP machine, described in Build Your Own Z80 Computer by Steve Ciarcia.  It consisted of three 74367 6-Bit Non-Inverting Drivers, and two Intel 8212 8-Bit Input/Output Ports*.

The 74367 chips acted as the address bus buffer, leaving 1/3 of one of the chips unused.  The 8212 ports were wired back to back, using BUSAK to disable the address bus drivers, and RD to switch between the Input configured 8212 and the output configured 8212.

Once I got to building the circuit on the breadboard in anticipation of my initial LED test, I started to realize that my chip count was going to be very high, and there was a LOT of wiring involved in the buffering alone.

I took a step back from the project for a bit, and browsed around Digikey and Jameco, read a few datasheets, and I'm thinking that using a pair of 74LS541 Octal Tri-State Line Drivers for the address bus and a 74LS245 Octal Tri-State Transceiver for the data bus might be the way to go.  It certainly simplifies the wiring and lowers the chip count.




* The 74412 appears to be pin compatible with the 8212.  I have not evaluated the datasheets of both parts to know whether the 74412 can be a direct replacement or not, but I did use it rather than create a new library footprint in Eagle.  Check the datasheet before using the 74412.




Wednesday, January 28, 2015

Z80 Computer

Work has begun on a project that I have wanted to do for many years, and put off for one reason or another.  A few months ago, I decided that I wanted to (finally) build a Z80 machine from scratch, get it to run CP/M, and play a game of Zork.  I hadn't the foggiest idea what it would take, but I have picked up a touch of electronic and programming background over the years, so I decided to take a hack at it.

After a few months of research, design, and waiting for shipping, the first breadboards are starting to go together.  The machine will be a Z80A CPU running at 4MHz with 64k of RAM and 32k of ROM.  I intend to use a Zilog Z80-SIO with a MAX232 to communicate with an old NEC dumb terminal that I have laying around for control.

So far I have constructed the clock, the reset circuit, a single-instruction step circuit, and the beginnings of the bus buffering and signal/address decoding.  I intend to detail each circuit in an individual post including relevant schematics and measurements.


My first test will come shortly, once I finish wiring up the buffers.  I will be pulling the entire data bus low, and hooking LEDs to the buffered address bus output.  If all goes well, the CPU will read NOP off of the grounded data bus, and proceed to increment the address bus every time I run the single-instruction stepper.  The end effect -- A 16 bit binary counter.

From there, I can go into decoding, RAM/ROM, peripherals, some kind of storage, writing a ROM monitor, writing a custom CP/M BIOS, and on, and on, and on.  Oh well, I needed a project and more material for this blog anyway, and from the looks of it, I've got plenty to do now.

Wednesday, October 1, 2014

Patching Debian 5 for ShellShock

Debian 5 is, sadly, no longer supported by the friendly folks over at Debian.  Like the rest of the internet, it's default version of bash is quite vulnerable to the ShellShock vulnerability.

To clean up the mess we have going here, start off by ensuring that the system is up to date (Debian 5.0.10 is the latest in the repositories.  If you haven't already switched over to the archive sites for the upstream repositories in order to get package updates, update your /etc/apt/sources.list to point at the Debian archives (see the FAQ section at https://wiki.debian.org/DebianLenny).  Then run an 'sudo apt-get update && sudo apt-get upgrade'.

Post-upgrade, /etc/debian_version should show the system at 5.0.10.  In order to update bash, grab the bash-3.2 sources here:  https://ftp.gnu.org/pub/gnu/bash/bash-3.2.tar.gz

Unpack them, and run a bit of bash to patch the sources up to 3.2.55:

#!/bin/bash

wget https://ftp.gnu.org/pub/gnu/bash/bash-3.2.tar.gz
tar -zxvf bash-3.2.tar.gz
cd bash-3.2

for x in `seq 1 55`
do
    curl https://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-`printf "%03d" $x` | patch -p0;
done

./configure
make
make tests

Then do the standard GNU install with "sudo make install".