Philips Hue – R.E. Whitepaper from Black Hat 2016

At Black Hat 2016 I presented on some reverse engineering of the Philips Hue (also see my other post about getting root on it, which was part of that presentation). As part of my presentation I had a little bit of bonus material by Eyal Ronen (which was, I think, the coolest part of the presentation).

Eyal can’t yet publish the details, but see http://www.wisdom.weizmann.ac.il/~eyalro/PhilipsHueTakeOver/ for some of the demos. You can see his website for more research related to the Hue as well, and follow him on twitter @eyalr0.

Summary of the work (to make it clear):

  • I did NOT make a worm. The title was a question someone asked me, and the talk is about the security of the Hue.
  • The ‘Long Range Take Over’ attack was entirely done by Eyal Ronen – it was a cool demo & it’s very new research on his part. Do not credit me with that.
  • Philips did a rather good job (all things considered). The only trade-off I really call out is reuse of encryption keys across all FW updates for all devices, which is basically what makes a theoretical worm possible.
  • Rooting the Hue (earlier post) is a local attack and very nice for hardware hackers. There are unique root passwords which is a great security step, so far I haven’t found flaws in the Hue Bridge 2.0 besides that.
  • There’s a lot of “interesting vectors” which the talk goes over. Given enough time some of them may give, but it’s a question of who is motivated enough to spend a lot of time on them.

You can get the full slides here too:

Philips Hue Reverse Engineering (BH Talk ‘A Lightbulb Worm?’) Slides [PDF, 8MB]

Here’s a copy of the very large whitepaper (not updated with Eyal’s newer stuff):

Philips Hue Reverse Engineering (BH Talk ‘A Lightbulb Worm?’) Whitepaper [PDF, 5MB]

This whitepaper is a bit of a ‘data dump’ and ~48 pages of random stuff. But useful if you are interested in pushing this further!

Black Hat Slides – PIN-Protected HD Enclosure / MB86C311A Research

This is a quick post to link to slides from my Black Hat USA 2016 work.

This work stands directly on the work done by Joffrey Czarny & Raphaël Rigo presented at HardWear.io last year (2015). They discovered the issues w.r.t. the stream-mode cipher being used by all manufactures on the MB86C311A, and the fact that secrets are stored on the HD itself. Their work is available at:

They have some newer work coming out which looks to be very interesting, so please keep your eyes out for that. Anyway onto my stuff. The following is a link to my slides:

Brute-Forcing Lockdown Harddrive PIN Codes [Slides]

 

Getting Root on Philips Hue Bridge 2.0

This post will briefly show you how to get a root console on the new Philips Hue Bridges (the square ones). It’s rather easy, the only special tools you require are a USB-Serial cable & a torx screwdriver.

P1080978

There’s a video with full details, this post is just the specifics if you don’t want a very boring walk-through:

  1. For the serial cable (a standard 3.3V type one, DO NOT use a 5V cable), there is a 6-pin header along the bottom. Pin ‘1’ has a square footprint, and counting from pin 1 the connections are:
    Pin 1 = GND
    Pin 4 = RX In (connect to TX Out of your serial cable)
    Pin 5 = TX Out (connect to RX in of your serial cable).

    P1080980

  2. The bottom left-corner of the 2-row header is GND. You’ll have to short that with a wire to the following test point:

    P1080981
    This test-point is shorted to GND with a paper-clip or wire. Click image for full-sized to see in better detail.
  3. To get the system working, check you are getting boot messages. Now, restart the system and after you get a bit of output, short the pin. You might see some output like this:
    U-Boot 1.1.4 (Sep  8 2015 - 04:08:21)
    
    bsb002 - Honey Bee 2.0DRAM:  
    sri
    Honey Bee 2.0
    ath_ddr_initial_config(195): (16bit) ddr2 init
    tap = 0x00000003
    Tap (low, high) = (0x8, 0x22)
    Tap values = (0x15, 0x15, 0x15, 0x15)
    64 MB
    Top of RAM usable for U-Boot at: 84000000
    Reserving 214k for U-Boot at: 83fc8000
    Reserving 192k for malloc() at: 83f98000
    Reserving 44 Bytes for Board Info at: 83f97fd4
    Reserving 36 Bytes for Global Data at: 83f97fb0
    Reserving 128k for boot params() at: 83f77fb0
    Stack Pointer at: 83f77f98
    Now running in RAM - U-Boot at: 83fc8000
    Flash Manuf Id 0xc8, DeviceId0 0x40, DeviceId1 0x13
    flash size 0MB, sector count = 8
    Flash: 512 kB
    *** Warning *** : PCIe WLAN Module not found !!!
    In:    serial
    Out:   serial
    Err:   serial
    Net:   ath_gmac_enet_initialize...
    Fetching MAC Address from 0x83febe80
    Fetching MAC Address from 0x83febe80
    ath_gmac_enet_initialize: reset mask:c02200 
    Scorpion ---->S27 PHY*
    S27 reg init
    : cfg1 0x800c0000 cfg2 0x7114
    eth0: 00:03:7f:11:20:ce
    athrs27_phy_setup ATHR_PHY_CONTROL 4 :1000
    athrs27_phy_setup ATHR_PHY_SPEC_STAUS 4 :10

    Which will then fall back to a prompt:

    ath>

    Good news! We can now get everything working for you. You can print the existing variables if you wish:

    ath> printenv
  4. Set a boot delay such we can enter the menu without the boot hack:
    setenv bootdelay 3

    Check it works with

    printenv bootdelay

    and confirm you get a line like this:

    bootdelay=3

    Finally, save the setting with:

    saveenv

    You can now reset the system (use the ‘reset’ command), and confirm there is a count-down that gives you time to hit “enter” and get this prompt again.

  5. Now let’s fix the root password. Before doing this, I suggest you keep a copy of the old value:
    printenv security

    This would let you restore things back to default. Then the following will set the root password to ‘toor’:

    setenv security '$5$wbgtEC1iF$ugIfQUoE7SNg4mplDI/7xdfLC7jXoMAkupeMsm10hY9'

    You may have to copy this into notepad first to ensure it all fits on one line! The quotes are critical here. Again check it works with printenv, then type saveenv to store things to disk.

    If you want your own password, simply use the ‘mkpasswd’ command in Linux to generate an appropriate string.

  6. Once again reset the board – assuming you used saveenv, that root password will be used by the system now. You should be able to log in with root/toor!
  7. Once you are in, there’s a few changes you’ll want to make. We’ll edit the file /etc/rc.local:
    # vi /etc/rc.local

    And add the following:

    iptables -I INPUT -p tcp --dport 23 --syn -j ACCEPT
    telnetd

    This will open the telnet port & start the daemon on boot. Write the file and quit with :wq. You may also want to add the /etc/rc.local to the /etc/sysupgrade.conf file to avoid it being overwritten in the future.

    See the comments below – someone found a way to get ‘dropbear’ to allow root login too.

  8. Try using telnet to connect now. You can find the IP of the bridge using ifconfig, but you can also get it through the Hue app.You can also try using “Philips-hue.local”, which I’d first check via ping to see if it resolves:
    ping Philips-hue.local
  9. I’ve done the 25-July-2016 update without issue too (after first rooting the hub with an earlier version). I’ll continue to update this as updates happen.

BONUS – How did I figure this out?

The “bomb out to uboot prompt” is a known bug. Once in the prompt, I could edit the bootarg command with this:

setenv std_bootargs 'board=BSB002 console=ttyS0,115200 ubi.mtd=overlay rootfs=/dev/mtdblock:rootfs rootfstype=squashfs noinitrd init=/bin/sh';

This gives me a shell which doesn’t require a login. But many things are broken/disabled in this mode. It was however enough to find that there is another script that runs on startup which uses the uboot env variable, and copies it into the shadow file for the root password.

With this knowledge it’s easy to use mkpasswd to make an appropriate shadow file entry. Easy!

I also checked with two different Hue Bridge v2.0 devices. They contained different root passwords (at least different salts). I’ve been told the root passwords are indeed unique per device, which is a good step to stop someone from attacking your virgin Philips Hue 2.0 bridge.

As an interesting note – other people have also discovered this independently of me. Between writing this post & actually linking it from anywhere (i.e., so you could actually find it) pepe2k figured out the same thing on a forum post.

As well someone else did this same “overwrite root” attack already, but had used an external programmer to write the FLASH memory chip:

So it’s worth considering that many devices may be broken even if there isn’t some fancy Black Hat talk or otherwise. Most of the attacks (such as this one) are fairly well-known and pretty basic.

UPDATE: At DEFCON 24, I guess someone gave this type of attack a marketable name. You can see the idea called pin2pwn here.

A Low-Cost X-Y Scanner using 3D Printer

This summer, our summer intern Greg d’Eon made a quick project to build a X-Y Scanner from a 3D printer (by ‘quick’, I mean it took him less than 2 days!). You can see the source code up on GitHub. Anyway, 3D printers are very nice as they have fairly high resolution and fairly low cost. Here’s a quick video:

We’re using it to measure EM emissions frequencies over a PCB, but you could also use this for side-channel emissions, or fault injection. While the resolution might not be high enough for getting at specific features on a chip surface, it can still be used for general positioning.

With your EM emissions, you can graph X-Y vs. amplitude – here I’ve constrained the range to get an idea where the 96 MHz emissions are concentrated. Probably more interesting would have been to use a 2D plot with colour overlaid over the PCB design:em_plotYou can also do things like plot frequency vs. position with strength of the signal given by color. In the following graph the X position is fixed, and only the Y position is varied. You can see here the 96MHz oscillator of the SAM3U microcontroller on the ChipWhisperer-Lite for example:

650MHz_05

 

Low-Cost SMD Soldering Setup

The following blog post shows some details of my SMD soldering process. This was based on a larger video I did (linked below) showing the entire soldering process.

Video of Soldering Setup

The following shows me soldering a complete board with BGA device.

Equipment Used

In the above video, there are several pieces of equipment used. The following shows you some of the important ones.

Reflow Oven

I’m using a T962A reflow oven. I recommend this over the T962, which is a smaller version. The T962A has 3 heat lamps so has a more even heat distribution. Be aware you can’t use the full surface area – about the middle half I find is successful, but depends a little on complexity of the PCB.

I specifically purchased mine from this seller on AliExpress, check other sellers as prices change over time. You might turn it on quickly to confirm it works, but before doing much there are some important fixes:

  • Removing masking tape, replace with Kapton (Polymide) tape. See instructables post for details.
  • Fixing missing ground connections. Some versions have poor grounding between the outer (metal!) case and the wall plug. See the wiki page for a photo of this fix.
  • Updating the firmware and adding a cold-junction sensor. This is the most complex task, and requires soldering a DS18B20 to the mainboard, then using a USB-Serial adapter to reflash the firmware. See the front page of the T962-Improvements Github Repo, which has links to the required soldering. There is also an optional fix to reduce the very noisy small fan.

Fume Hood

I built a fume hood out of the following:

  • 2×4’s for frame.
  • Thick plastic drop-sheet.
  • Powerful vent booster fan with variable speed control.
  • Active charcoal oven range hood filter (mounted in top of fume hood).
  • Active charcoal filter for car cabin (mounted in cardboard box used as exhaust).

You can also improve one out of a range hood from an oven. See video for general fume hood construction.

Manual Pick-n-Place

FIG4

This requires three things:

  1. Vacuum pump, which you can make from a Tetra Whisper pump (see instructables link). Get some of the nice silicon tubing at the same time (like $3 from Amazon).
  2. Syringe with hole drilled into body. You can get syringes (don’t need the pointy bit!) from pharmacy, or order from Newark/Digikey. When you cover the hole, you force the vacuum through the tip, picking up the part. Release your finger from the hole to drop the part. See the above video for details.
  3. The tips for pick and place, which are “Luer Lock” needles bent slightly (for small parts) or commercially available tips (for larger parts).

The tips are the only somewhat tricky thing. I had a good selection from a previous SMD picker tool, something like this kit for example (which is Chip Quick Inc. part #V8910). These tips are actually the same “Luer Lock” that fits into syringes, check E-Bay for cheaper kits:

V8910 Chip Quik Inc. | V8910-ND DigiKey Electronics

You can also buy Chip Quik Inc part #VCS-9-B which has a bunch of these tips. It’s not the cheapest way, but if you are in a hurry will do! But all of these tips are for larger parts (i.e. maybe SOT23-3 at smallest). If you get into chip resistors, you need to go smaller.

For the small parts, you can bend “needle tips” slightly. You can buy packs of 50 from Digikey (search “Luer Lock”), but might find it cheaper to get individual ones from either medical supply places, or buying products which use them. For example some static-safe squeeze bottles come with a few tips. Again the expensive but easy route is Chip Quik part # SMDTA200 which has a bunch of different sized tips.

http://media.digikey.com/Photos/Apex%20Tool%20Photos/KDS2312P.JPG

Stencils

There is three main options for stencils:

  1. Laser cut stainless steel.
  2. Third-party cut Kapton film.
  3. Self-cut Kapton/Mylar film.

For laser-cut stainless steel, this can typically be ordered with your PCB fab. For example 3PCB.com and Dirty PCBs offer them very cheaply (~$25) when ordering PCBs. This is almost always the best choice, as the stainless steel stencils are very reliable and I’ve had great success with BGA devices.

You can also use third-party services to cut Mylar or Kapton film for you. OSHStencils is one example of a supplier.

Finally, you can make your own. You’ll need some practice to cut BGA parts, but it’s quite easy to cut stencils for less demanding applications. I have a previous blog post on my method.

I’ve been making my own stencils with this process for some time with great success.

FIG3

Solder Paste/Squeegee

I purchased the squeegee from Dirty PCBs. There are some other blog posts on squeegee options you might look at.

I generally just buy solder past from Digikey. Digikey does a great job of cheaply shipping to Canada, and the paste comes in an awesome cold pack thingy that keeps it cool during the trip. Chip Quik (again with the Chip Quik sorry, I don’t have a connection with them but just end up using their stuff!) sells some nice small syringes. Be aware it does have a shelf life… I’ve used past about 6-12 months paste that date, but you will eventually see issues (balling, flux separates). I recommend keeping to the suggested date to avoid giving yourself the headache of discovering your paste is bad after you’ve tried soldering your PCB. The cost of all your parts is probably a lot more expensive than the cost of replacing your paste.

 

SECT-2015 Talk Slides

On Friday at 14:15 I’m giving a talk about my open-source power analysis and glitching projected called ChipWhisperer at SEC-T. Here is some useful links if you watched the presentation:

See information about the entire project at www.ChipWhisperer.com too! Video will be posted online at some point too.

ESC SV 2015 – USSSSSB: Talking USB From Python

At ESC 2015 SV I gave a talk on using USB From Python, see the talk description here. This blog post is serving as a placeholder to allow me to update links to software used during the live demo.

For SuperCon 2015, there is a Project Page with these details too. You can also ask questions on the project page.

Download Slides

There is two versions of the slides. Use the SuperCon slides, but I left a copy of the ESC ones here in case you wanted the original for some reason.

Download Slides from Hackaday SuperCon 2015 (Newer Version for SAMD21) [PDF, 10MB]

Download Slides from ESC2015 (Older version for SAMD11) [PDF, 10MB]

Tools to Install

  1. Atmel Studio 6.2
  2. WinPython-2.7
  3. libusb-win32-devel-filter (NB: No need to open the filter install wizard when done)
  4. USBView

SAMD11 Errata

For ESC I used a SAMD11 device, which needs a bit of a hack.

There is a bit of an “oopsie” in the SAMD11 devices. This bug isn’t in the official errata yet, and I’ve been told it’s limited to engineering sample devices (which were used in some of the early dev boards).

Basically the 48MHz oscillator calibration byte is wrong, and you need to manually tune this. You’ll know this problem exists as the device won’t be detected by Windows:

usbbad

The work-around isn’t super-fun. First, use the programming interface to see the starting value of the DFLL48M_COARSE_CAL fuse:

pllbad

Next, search in the source code for reference to the dfll_conf.coarse_value variable. You will find where it is being setup, and you can override the value. Basically you have to experiment a bit to find a working value:

pllhack

 Reference Code

USB Test – Slide 87

import usb.core
dev = usb.core.find(idVendor=0x03eb, idProduct=0x2402)
print dev

If you get “None”, make sure you installed the “Filter Driver” using the LibUSB tools!

Control Endpoint Read – Slide 94

import usb.core
dev = usb.core.find(idVendor=0x03eb, idProduct=0x2402)
dev.set_configuration()

data = dev.ctrl_transfer(0b10100001, 0x01, 3<<8, 0, 4)

print data

If you get a “device is not functioning” error just skip this one…

Sending Output Report

import usb.core
dev = usb.core.find(idVendor=0x03eb, idProduct=0x2402)
print dev

dev.set_configuration()

data = [ord('1'), ord('1'), 0, 0, 0, 0, 0, 0]
dev.write(0x02, data)

Receiving Input Data (Press button to see change)

import usb.core
dev = usb.core.find(idVendor=0x03eb, idProduct=0x2402)
print dev

dev.set_configuration()

for i in range(0, 10):
    while True:
        try:
            test = dev.read(0x81, 8, timeout=50)
            break
        except usb.core.USBError, e:            
            if str(e).find("timeout") >= 0:
                pass
            else:
                raise IOError("USB Error: %s"%str(e))
     
    print test

 Full GUI Example

#Public domain - simple USB GUI Example by Colin O'Flynn

from PySide.QtCore import *
from PySide.QtGui import *
import usb.core
import sys

class USBForm(QDialog):
    def __init__(self, parent=None):
        super(USBForm, self).__init__(parent)
        self.setWindowTitle("ESC 2015 Demo")

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.pbConnect = QPushButton("Connect")
        self.pbConnect.clicked.connect(self.con)
        self.isConnected = False

        self.pbLED = QPushButton("LED Blinking")
        self.pbLED.setCheckable(True)
        self.pbLED.clicked.connect(self.changeLED)
        self.pbLED.setEnabled(False)

        layout.addWidget(self.pbConnect)
        layout.addWidget(self.pbLED)

        self.swStatus = QLineEdit()
        self.swStatus.setReadOnly(True)
        layout.addWidget(self.swStatus)

        self.butTimer = QTimer(self)
        self.butTimer.timeout.connect(self.pollButton)


    def con(self):
        if self.isConnected == False:
            #Do USB Connect Here
            self.dev = usb.core.find(idVendor=0x03eb, idProduct=0x2402)
            self.dev.set_configuration()

            #Sync changeLED
            self.changeLED()
            
            self.isConnected = True
            self.pbConnect.setText("Disconnect")
            self.pbLED.setEnabled(True)
            self.butTimer.start(100)
        else:
            self.isConnected = False
            self.pbConnect.setText("Connect")
            self.pbLED.setEnabled(False)
            self.butTimer.stop()

    def changeLED(self):
        if self.pbLED.isChecked():
            #Send command to make LED on
            self.dev.write(0x02, [ord('1'), ord('1'), 0, 0, 0, 0, 0, 0])

            self.pbLED.setText("LED On")            
        else:
            #Send command to make LED blink
            self.dev.write(0x02, [ord('0'), ord('1'), 0, 0, 0, 0, 0, 0])
            self.pbLED.setText("LED Blinking")

    def pollButton(self):
        try:
            data = self.dev.read(0x81, 8, timeout=50)
            if data[0]:
                self.swStatus.setText("Button Pressed")
            else:
                self.swStatus.setText("Button Released")
                
        except usb.core.USBError, e:
            if str(e).find("timeout") >= 0:
                pass
            else:
                raise IOError("USB Error: %s"%str(e))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = USBForm()
    form.show()
    sys.exit(app.exec_())

Side-Channel Power Analysis of AES Core in Project Vault

What is Project Vault

You can read a quick overview on various news sites, but basically project vault gives you a cryptographic module that you have complete control over. This means *you* decide to trust the module – even to the point of being able to access to implementation details of the crypto cores.

Basically Project Vault is a solution to how you can avoid having unknown backdoors in your hardware. Rather than having to trust some vendor of security modules, you can make sure things are done correctly.

About the AES Core

The crypto modules have a nice description, which you can read here. Of interest to us is this statement:

The AES core can encrypt and decrypt blocks of data in three modes of operation: AES-128, AES-192, and AES-256.  The design is based upon a purely gate logic implementation of the forward and reverse sboxes due to the work of Boyar and Peralta.  This avoids differential power attacks present in purely lookup table or SRAM based sbox implementation.

The paper in question isn’t written by Andy Samberg’s character on Brooklyn Nine-Nine, but instead is referencing A small depth-16 circuit for the AES S-Box (that link is the unpaywalled version, the paper was published in the SEC 2012 proceedings).

This is a problematic statement, as side-channel power leakage isn’t just one simple fix. In this case there is effectively no difference from an unprotected implementation for side-channel power analysis. More on that in a moment.

Side-Channel Power Analysis

It’s worth pointing out I’m looking at a single small part of the entire device. There may be additional protocol-layer protection that would significantly complicated the analysis I perform, I just have no idea as haven’t looked into that.

Realistically, side-channel power analysis might be a threat. Having a leaking core on it’s own might be impossible/very difficult to exploit due to use-cases. But it might form part of a larger attack (i.e. someone is able to take control of the core using a different attack method).

Side-channel power analysis (or Differential Power Analysis, called DPA) also requires the device is operating with the key we are using. You cannot use DPA on an encrypted hard drive sitting on the table for example – you could only use it to recover the encryption key as the drive is decrypting/encrypting something. If the encryption key comes from the user, this means DPA is useless against an encrypted drive you recovered from someone.

Because of these caveats I like to stress this isn’t some master attack. In fact the only thing that makes it noteworthy is the documentation claimed some level of DPA resistance. Anyway on with the attack…

Attack Theory

DPA attacks are based on small power measurements being correlated with either data values or changes in data. In the referenced paper from earlier, the DPA attack being prevented is that the input and output of the S-Box are never put onto the same register.

This means we could never see the difference in number of bits flipped from input to output of the S-Box. Thus the power analysis attack on the S-Box itself would fail, which is normally where an easy leak to stop is. But it’s not the only way.

Looking at the source code, we see the following Verilog lines during the encryption (similar lines for decryption):

            begin
                state <= state_new;
                if(round == round_max)
                beginS
                    data_o <= state_new;
                    busy_o <= 0;
                end
            end

This is problematic, as the 128-bit AES state is held in a register. That register is overwritten on each round. In particular, looking at the last round (this figure based on one shamelessly stolen from Frank Gürkaynak’s Thesis), note the “old value” to “new value”:

aes_state_desc

The ShiftRows is easily reversed (it’s just swapping around the location of bytes). This in fact means the input and output of the S-Box is effectively written into the same register, giving as an easy way to count bit flips (Hamming Distance). We can correlate expected number of bit transitions with measured power as in a standard DPA attack.

Attack Test

While it’s not really needed to test this in theory, nobody believes hand-waving. So I used a SAKURA-G FPGA board (Spartan 6 LX75) with my OpenADC and ChipWhisperer software, as I happen to have it around:

You could easily use my ChipWhisperer-Lite with any other FPGA board instead of the SAKURA-G. The SAKURA-G makes power measurement easier, otherwise you can use some H-Field probes etc.

There’s not a lot to this – I ripped out just the AES core (i.e. everything in this directory in the GIT). It’s easy to interface to the existing FPGA code given with the SAKURA-G, as the interface is almost exactly the same (key in, block in, block out, clk, go command).

There was a few cycles of synchronization error for some reason, but I used a “resync by sum of absolute difference” in my ChipWhisperer software. Here is what the raw power traces look like after resync:

aes-power

Running an attack targeting the last round-state difference of AES gives us a nice figure where the known encryption key bytes (in red) are filtering to the top of the “most likely encryption keys”, here with 2000 traces:

aes-pge

You can check where the leakage is occurring too. In the following figure the “correct” byte value is highlighted in red. You can see around sample ~342 there is the largest absolute peak of that correlation value, and it rises about all the wrong guesses. This corresponds to around the last round (based on power dips in earlier waveform):

aes-locationThat’s it! It’s really a standard Hamming-Distance attack against AES. The special S-Box design didn’t make our life any harder for my attack. Again this was done in a controlled environment, so it’s quite possible there are higher-level protections that make this attack much much harder.

Considering the device will (presumably) only have the encryption keys loaded when the user is doing stuff, it’s a pretty small risk. An attacker would have to monitor the power while you are using the device to deduce your keys… and if they are that close, they might just try seducing you instead.

 

Experiments with Seek Thermal Camera

A while back I got a Seek thermal camera, as I wanted to use it for measuring electronics component temperatures. As part of a course I’m teaching at Dal, I did a few experiments I wanted to post here. These photos were taken with a macro lense, shown here:

seeker

To get that lens, I purchased a 20mm diameter ZnSe Lens with 50.8mm/2″ focus off E-Bay for about $20. I ended up getting both a 100mm and 50mm focal length to try both. Then you need a holder, which I used one I found on Thingiverse. If printing again I’d try to enlarge the size of the space for the lens – I had to use a knife and considerably carve the inside step down. In fact I’d remove the middle ‘ridge’ which holds the lens in, and instead epoxy it.

The Tests

I’m using a TO-220 5 ohm resistor, which lets me reliably control the power being dissipated by the device. The part number is PF2205-5R which you can get at Digikey.

The first test compares mounting the resistor horizontally and vertically. To do this I’ve put two into a breadboard:

restest_overview

Which we power with constant power using my supply:

restest_powerinAnd can see the difference in temperature between the two:

restest_results

So what gives? There is (expected) to be two reasons for the temperature difference:

  1.  The vertical mount naturally causes airflow over the large back tab – heat will rise, and as heat comes off the tab, it cause a small amount of natural airflow.
  2. The horizontal mounted package is closed to the table surface which will further restrict airflow.

The majority of this comes from #1, but people will complain if I don’t mentioned #2. If your heatsinks has lots of fins, it’s worthwhile to ensure the natural airflow due to heat easily flows up the heatsink.

Also note the temperature rise is about what is expected of a TO220 package, which typically has about a 62ºC/W Junction to Case thermal resistance. Ambient is around 20C, so with 1W of power in we expect 20ºC + 62ºC = 82ºC case temperature. Cool!

The second test tries several mounting of TO220 packages on a PCB. The PCB setup is shown here:

restest_more

First, let’s look at the vertically mounted device. Here is the thermal image once it reaches steady-state:

restest_vert

What the hell happened? We still had 1W of input per transistor, but it’s 14C cooler than the other test!

In this case the PCB is dissipating some of the heat – the entire top and bottom are solid copper pours, each side connected to one of the pins. This is almost idea for heat transfer.

Next, let’s look at the other two resistors. The following shows both details of the mounting and the steady-state temperatures:

restest_doubleI should mention the reflection areas have low thermal emissivity, and the Seek camera doesn’t pick them up correctly. Thus the tab & PCB area without solder-mask aren’t actually cooler.

Anyway you can see that mounting the package *close* to a good heatsink but without actually touching it is worse than free-space mounting. Having a good connection (in this case soldering) as expected further reduces the case temperature by allowing the PCB to dissipate more of the heat.

The “close but not touching” comes up a lot – for example if you make a simple metal shield for your device, you might think it a good idea to have the shield come close to heat-producing devices. But unless it actually makes good contact, you are probably hampering the natural convection air currents!

When I get some more time I plan on buying a few different heatsinks from Digikey and compare my measured temperature rise with the theoretical temperature rise.