PICkit 4

Illustration

If you are already using PICkit 3, the first thing you’ll notice about PICkit 4 is increase in thickness and width alongside additional 2 pins on it ICSP connector. Finally PICkit can program (and debug) both PIC and Atmel microprocessor family. So let me compare it against it’s predecessor…

As far as I can deduce, there are two reasons for increase in thickness. First one is button/LED mechanism that actually takes quite a lot of space in front of the board. Old system of having button just stick through the plastic allowed shell to get closer to PCB while LED pipe and internal button simply need more space. That said, although I was skeptical about the button and accidental presses, it seems to work fine for now - whether it’ll age well remains to be seen.

The other reason for the thickness is addition of the SD card slot intended for use with programmer-on-the-go functionality. I say “intended” as functionality is still not available, continuing Microchip’s tradition of removing functionality with the new PICkit only to return it slightly worsened later. As an optimist I will assume this will allow for storing of multiple firmware images (for both PICkit and device). User interface will be hell with only a single button and RGB LED but it would make some sense.

Illustration

However, assuming functionality ends up working as on PICkit 3 with the only one firmware image, I’ll consider it to be over-engineered nonsense. A few hundred kilobytes required for a single firmware image could have been stored on internal memory chip probably even cheaper than what SD card slot costs.

Looking inside, I was surprised to see Atmel ATSAME70Q21 as the main chip (PICkit 3 was using PIC24FJ256). I find the change neither good or bad on it’s own but such completely different platform might justify abandoning updates to PICkit 3 sooner than expected.

Illustration

Despite the wider ICSP connector, I saw no obvious reason for device to get wider either. PCB is not really densely populated and I could bet engineers could have fit all in PICkit 3 case with a bit of effort. That said, I must admit that I like the look of new PICkit better. And yes, new shape is a bit less comfortable on hand, but I could live with it. New looks with the old case size, now that would be something. :)

The first 6 pins of the new connector are fully compatible with the old PIC ICSP and that means you can still directly connect it to any of your old board (assuming PICkit can still fit). If you are using pogo pins you can opt to get a wider (8-pin) pogo connector or just continue using the existing 6-pin one if you don’t need Atmel.

Microchip opted to use micro-B USB connector and I hate them for it. While I would understand PICkit 3 coming with the same, in 2018 Microchip should have used USB type C. It’s about the same size as micro-B but it allows for orientation agnostic plugins. With PICkit 3 it was less of a trouble as mini-B is bit and visible connector but with the new PICkit there is always a need for the three-way handshake.

Illustration

I love the reset button next to USB connector but not for it’s reset functionality. Who’s gonna search for a paperclip to reset the device when unplugging/plugging into USB will do the same? I love it because you can see the main LED through its hole. If you are programming board with your PICkit in vertical position, you will get used to looking at LED from above instead of craning your neck on the side. This is probably the best addition there is.

Experience from MPLAB is pretty much the same as it ever was. You still need to download image into programmer for every damn PIC you use. When you switch between projects there is always a wait and need for Internet connection as it was with PICkit 3. Programming experience itself is similar to PICkit 3 and slightly faster.

All in all, if PICkit 4 was a straight upgrade from PICkit 3, I would hate its bulkiness much more as it does feel more unwieldy than PICkit 3. However, considering PICkit 4 is a single programmer allowing for both Atmel and PIC microcontrollers to be programmed I do think of it as a step forward.

Attacking WPA2 PSK And Mikrotik Fix

Illustration

With everybody awaiting WPA3, it’s easy to miss improved WPA2 attacks. Up until recently cracking the WPA2 with pre-shared key required online attack. Well, not anymore.

This new attack doesn’t even require waiting for 4-way handshake - essentially all you need is a few minutes of passive traffic, minimal amount of luck, and a bit of alone time to crack the key - offline. If you are willing to go active capture time goes down to a second and no luck is involved. The only real challenge is offline cracking - and there is no time pressure here.

Without going into too many details, issue is in optional PMKID field that does come in handy for roaming support. Unfortunately, for most routers, PMKID gets sent even if roaming option is off.

There are two “fixes” for this. The obvious one is to increase complexity of your pre-shared key while avoiding ones present in the precalculated SHA-1 tables. We are still talking about brute forcing SHA-1 hash - a non-trivial task if you have long and random password.

Second approach is to disable PMKID field and that would require you to upgrade router’s firmware. Fortunately for me, Mikrotik already has a fix available and thus avoiding it as easy as selecting to Disable PMKID.

Mind you, that’s not absolute protection as weak passwords are still vulnerable no matter how you cut it. But this does prevent offline attack.

Seattle Code Camp - Cryptography Failures

Illustration

As you read this another Seattle Code Camp talk is behind me and its time to share the slides.

Due to way how I structure my presentations, just slides alone will probably not work for you. However, if you still want to proceed or you were at presentation and you want slides for links and resources contained within, feel free to download them here.

Image.FromStream Doesn't Always Preserve Exif Data

Reading Exif files within C# is easy. For example, if you want to know camera model, it is enough to simply loop through image’s properties and read it:

private static string GetCameraModel(Image image) {
    foreach (var property in image.PropertyItems) {
        if (property.Id == ExifTag.CameraModel) { //0x0110
            return ASCIIEncoding.ASCII.GetString(property.Value).Trim('\0');
        }
    }
    return null; //no model found
}

However, if you want to do anything with the file you cannot simply load it with Image.FromFile as .NET keeps image open all the way until disposal. Easy enough, just load image with Image.FromStream, like this:

Image image;
using (var stream = new FileStream(this.File.FullName, FileMode.Open, FileAccess.Read)) {
    image = Image.FromStream(stream);
}
return GetCameraModel(image);

Image loaded in this manner will not contain any Exif - just the image data. The default stream loader just tossed everything that’s not picture away. If you want to preserve picture, you need to explicitly tell it:

Image image;
using (var stream = new FileStream(this.File.FullName, FileMode.Open, FileAccess.Read)) {
    image = Image.FromStream(stream, useEmbeddedColorManagement: true, validateImageData: true);
}
return GetCameraModel(image);

Now you can read all the Exif data you can handle. :)


PS: Interestingly, it seems that on Windows 7 it works either way.

Random on 8-bit PIC

When dealing with 8-bit microcontrollers one doesn’t always have all facilities taken for granted on a computer. One such example is a simple random number. While all computers can easily provide you with random number at will, unless you have a heavily specialized PIC, real random numbers are out of your reach. However, there is a way to get sufficiently close to make it work for most non-cryptographic purposes.

The answer is in linear-feedback shift registers. Assuming polynomials are carefully chosen, it is relatively easy to get non-repeating 255 byte sequences on 8-bit PIC. Yes, they are not random but for the most purposes they are random enough.

There are many types of LFSRs, Fibonacci’s being the most famous and probably the one implemented most often due to its simple hardware structure. However, for the PIC device, Galois has similar enough properties with a much simpler software structure.

General Galois function might looks like this:

#define GALOIS_POLYNOMIAL 0b11010100; //x^8+x^7+x^5+x^3+1
uint8_t randomState;

uint8_t getRandomByte() {
    unsigned bit = randomState & 0x01;
    randomState >>= 1;
    if (bit) { randomState ^= GALOIS_POLYNOMIAL; }
    return randomState;
}

This function essentially takes whatever data has in previous step and, using one of the maximum sequence length polynomials, calculates the next random byte. However, if you run it as such you might or might not get anything other than 0. Why? Well, pesky sequence has one blind spot - number 0. You can get any 255 byte sequence assuming it does not contain 0. If data becomes 0, it will stay 0.

Knowing this, one might be tempted to simply initialize data to some number and call it a day. Indeed, that would work for many applications that use 8-bit PIC. However, there are two things to have in mind: sequence will repeat every 255 bytes and random number sequence will be exactly the same on every startup.

To deal with the issue of repeating sequences, we need a counter that will simply reset the sequence after it “runs out of bytes”. As LFSR “circles” back to the original value after going thru all permutations (assuming polynomial is selected well), the easiest approach is to remember first value and reinitialize inner state once that value comes up again.

Second problem is a bit harder but not impossible. While the hardware random source would be nice, we can also do without it. My favorite approach is to have 8-bit timer running (e.g. TMR4) and then execute something that doesn’t have deterministic time - for example any user interaction (e.g. button press), writing to EEPROM (if PIC has one), or just waiting for PLL lock:

//setup unused timer that runs of the clock
T4CONbits.T4CKPS = 0; no prescale
T4CONbits.T4OUTPS = 0; //no postscale
T4CONbits.TMR4ON = 1; turn on timer 4 (or any other timer)

PLLEN = 1; //enable PLL
while (!OSCCONbits.OSTS); //wait for PLL lock

If function takes a slightly different amount of clock cycles every time, your timer will be in reasonably random state every time you check it and you can use it as a seed for generating random sequence - just don’t forget to ensure it is not zero.

Thus, our simple generator of random numbers could look something like this:

#define GALOIS_POLYNOMIAL 0b11010100; //x^8+x^7+x^5+x^3+1
uint8_t randomState = 0;
uint8_t randomStart = 0;

uint8_t getRandomByte() {
    if (randomState == randomStart) {
        randomState = (randomState ^ TMR4 ^ polynomial) | 0x80; //ensure non-zero at the cost of LSB
        randomStart = randomState;
    }

    unsigned bit = randomState & 0x01;
    randomState >>= 1;
    if (bit) { randomState ^= GALOIS_POLYNOMIAL; }
    return randomState;
}

If you run it for a while, you’ll notice something a bit disturbing. While start of the sequence is random, sequence is always the same. We need a way to make the sequence a bit more random. The cheap way to change this is to simply loop through all maximum length polynomial terms and thus extending our sequence from 255 to 4080 bytes.

Or, to break a pattern, you can even make switches in middle of sequence to make it a bit less obvious:

const uint8_t POLYNOMIALS[] = { 0x8E, 0x95, 0x96, 0xA6, 0xAF, 0xB1, 0xB2, 0xB4,
                                0xB8, 0xC3, 0xC6, 0xD4, 0xE1, 0xE7, 0xF3, 0xFA };
const uint8_t POLYNOMIALS_COUNT = 16;
uint8_t polynomial = 0xB8;

uint8_t randomState = 0;
uint8_t randomIndex = 0;

uint8_t getRandomByte() {
    if (randomIndex == 0) {
        randomIndex = (TMR4 >> 6) + 1; //generate number 1 to 4
        randomState = (randomState ^ TMR4 ^ polynomial) | 0x80; //ensure non-zero at the cost of LSB
        polynomial = POLYNOMIALS[TMR4 & 0x0F]; //select next polynomial
    }
    randomIndex--;

    unsigned bit = randomState & 0x01;
    randomState >>= 1;
    if (bit) { randomState ^= polynomial; }
    return randomState;
}

Realistically, there is only so much you can do without any random entropy while keeping function reasonably fast and I think this final function gives a reasonable result.


PS: Again, do not use this for anything security related - for that you need real random numbers, not pseudo-random sequences.

PPS: Jason Sachs has a nice article going a bit deeper in details about LFSRs.

PPPS: If you really want to expand random sequence, think about using 16-bit state and polynomial. Albeit the price of 16-bit computations on a 8-bit microprocessor is non-negligible (albeit not devastating), your use case might warrant such step.