A small list of C brainteasers

Here's a small list of C brainteasers that a few friends and I came up with and/or found. (All problems, except where specified, in C99.)

  • Can you write some C of the form sizeof ( ... printf("hey!\n") ... ) which results in hey! being printed?
    • No, you may not put a close paren in the first ....
    • sizeof comes in two forms in C -- sizeof ( TYPENAME ), and sizeof EXPRESSION. Can you do it with both forms?
    • Can you do it without emitting any warnings?
  • Can you write some C that has the tokens [ * ] in a row?
  • How about the tokens restrict 5?
  • Can you write an a.c that results in:
jwise@jwise-lt-linux:~$ grep '#' a.c
jwise@jwise-lt-linux:~$ grep '{' a.c
jwise@jwise-lt-linux:~$ cc -std=c99 -pedantic -Wall -o a a.c && ./a
hey!
  • ... portably?
  • Can you write an a2.c that results in:
jwise@jwise-lt-linux:~$ grep '#' a2.c
jwise@jwise-lt-linux:~$ grep '{' a2.c
jwise@jwise-lt-linux:~$ grep '\[' a2.c
jwise@jwise-lt-linux:~$ grep '"' a2.c
jwise@jwise-lt-linux:~$ grep "'" a2.c
jwise@jwise-lt-linux:~$ gcc -std=c89 -pedantic -o a2 a2.c && ./a2
hey!
  • ... portably?
  • Can you write a program a3.c that results in:
jwise@jwise-lt-linux:~$ grep '"' a3.c
jwise@jwise-lt-linux:~$ grep "'" a3.c
jwise@jwise-lt-linux:~$ grep ';' a3.c
jwise@jwise-lt-linux:~$ gcc -std=c99 -pedantic -Wall -o a3 a3.c && ./a3
hey!
  • Portably?
  • Can you write a program a4.c that results in:
jwise@jwise-lt-linux:~$ grep '"' a4.c
jwise@jwise-lt-linux:~$ grep "'" a4.c
jwise@jwise-lt-linux:~$ grep ';' a4.c
jwise@jwise-lt-linux:~$ grep -E '{[^}]|{$' a4.c
jwise@jwise-lt-linux:~$ gcc -std=c99 -pedantic -Wall -o a4 a4.c && ./a4
hey!
  • Without using the tricks from a or a2?
    • The only implemenation I know of requires the compiler to take a specific view of the specification; you'll need gcc's view of the specification, not clang's.
  • (taken from elsewhere on the Web) Without running it, what is the output of the following program? int main(void) {int n = sizeof(0)["abcdefghij"]; printf("%d\n", n); return 0; }
    • It is not machine-specific.
  • A common idiom in C is assert(!"That's not gone well"). Unfortunately, a common idiom in C amongst careless programmers is assert("That's not gone well"), or the potentially even more amusing assert("!That's not gone well"). Can you write a macro that chokes with a compile time failure on the latter two cases?
    • More concretely: it is easy to write a static assert macro that fails to compile if a given expression is either a) false, or b) not compile-time constant. Your task is to write a static assert macro that fails to compile if a given expression is a) true and b) a compile-time constant!
    • Here are some test cases, if you care:
ASSERT_CHECKER(time());
ASSERT_CHECKER(0);
ASSERT_CHECKER("abc"[2]);
ASSERT_CHECKER(!"biteme");
ASSERT_CHECKER("biteme");
ASSERT_CHECKER(2 + 2);

The last two should fail, by the C99 specification. There is an easier way to do it with a GCC extension, but you do not need any GCC extensions to do this.

  • (C++11-only) Find a use for the token sequence .......

I've enabled comments below, but please don't post spoilers.

On Solving Hard Problems

Over the past few months, my primary role at work has been that of a bringup engineer: as a new part arrives, from the time the first silicon gets back until we hit production release, I'm involved in the team that shepherds the new chip through everything that needs to happen before we can ship it. This workload is somewhat bursty; some weeks, there will be little to do, but other weeks, I'll spend many many hours fighting fires, upon the discovery that parts of the system have critical flaws in them. Some of these experiences have been qualitatively different from things I've done before, while others have served to reinforce the lessons I learned in the past about how to work through, and ultimately solve, hard problems.

In this article, I've tried to capture and distill some of the lessons to take to heart. I've broken it up into a section containing the two overarching lessons that I found most useful to focus on (and wish that I had followed more in the past!), and then a section containing the remaining bits of strategy that I often otherwise find useful.

Phrases of note

The two lessons I found most important came in the form of phrases: one to pay rapt attention to, and one to pay rapt disrespect to. You may well find that these pop up in tougher problems that you might have worked through in the past, perhaps as steps towards the solution; after formulating them, I've found them to be somewhat unifying for my experiences. Hopefully, then, by being aware of these key phrases, difficult problems can be more easily reduced to tractable ones.

"That's funny."

Perhaps most apt as an introduction is Lester Freamon's quote from the first season of The Wire:

"We're building something here, Detective. We're building it from scratch. All the pieces matter."

Freamon, of course, was building a case against a regional drug and crime syndicate, not debugging. At the time he said it, though, there was something of a similarity between the tasks at hand; Detective Pryzbylewski was about to take an important piece of information, and mark it Non-Pertinent -- irrelevant. Freamon, in this scene, has picked subtle pieces of information out of the phone call that they were listening to that can make their case for them.

The same thing applies when working to root cause a bug. The title phrase that I allude to -- "that's funny" -- can be one of the most important. When you hear yourself or someone else remarking on something out of the ordinary, don't just put it aside -- find out what's going on! At the very least, write it down, so that it doesn't get lost; perhaps you'll find later that it ties in to confirm a hypothesis.

Three examples of this sort of insight (two from personal experience) come to mind:

  • In the golden years of America's space program, Apollo 12 took a lightning strike during launch2. Immediately afterward, many of the command module's systems began to misbehave in a confusing pattern that indicated wide systemic failure -- it appeared to be a product of multiple unrelated components all failing as a result of the strike. The mission was nearly deemed unrecoverable, and if no action was taken, would have become the Apollo program's only abort before entering orbit. However, one engineer called out to switch a power supply rail to auxiliary power; immediately, all of the apparently failed systems began reporting correct telemetry once again.

    This engineer solved the problem because he had traced down a similar scenario in a ground test many missions before. He saw a similar pattern of failures that seemed to be unrelated; in that case, however, a different test was being performed, and the navigation system failures were ignored. Later that week, he traced the issue down to a disconnected auxiliary power supply on that rail in simulation; when he flipped the switch back to "main" on the test module, the problem disappeared. In this case, the protocol of actively seeking to root cause what they called "funnies" saved a mission just a year or two later.

  • At one employer, I was called in to look at an issue in which a system worked OK with one version of a chip, but did not work with another version of what should have been the same chip. As far as we knew, the new version had a change in one of the pads, and nothing else. We knew that the system sometimes didn't boot at all, but what we had forgotten about was that sometimes, while the system was booting, driver initialization would take a long time, producing an error before continuing on. At the time, we chalked that up to general instability in preproduction drivers, but we had never seen that message before.

    We ultimately root caused the issue to an error in which we had also changed another similar pad. After we had independently diagnosed the issue, we realized that the message pointed directly to the specific inadvertent pad change, and an error condition that such a thing could trigger. Had we looked at the details of that message earlier, we would have been spared some hours of frustrating and stressful debugging.

  • In college, I took a class that was the closest thing our computer science department had to a capstone class: Operating System Design and Implementation. (It ultimately proved to be a formative experience for me, and I went on to TA it for quite some time.) One of the projects in this course is to write a kernel. During this project, I came across a peculiar issue: under particular types of loads, the virtual machine's display would fill with garbage, and the machine would crash. The crash was a "triple fault" -- something went very wrong with the system. By that point, the virtual machine's state was corrupted and no registers were available, since the triple fault caused the virtual CPU to reset. \ \ In retrospect, I wish I had taken note of the particular contents of the display. What I had previously believed to be garbage, surely, was not; it contained important information about what the system was doing at the time. The exact values of the garbage were meaningful! At the time, I wrote it off as simply a strange part of the crash syndrome, but there was much more to it than that. Paying attention to weird data would have saved a day or two of debugging.

"That's impossible."

In contrast to the previous phrase -- something that one should stick one's head out to look for -- the phrase "that's impossible" sometimes must be ignored in a difficult debug session. The job of the debugging engineer is to stop at nothing in order to find the root cause of a bug. The request to gather extensive data in a post-mortem session can be a good cause for one to say "that's impossible". However, even without access to the system's normal facilities for introspection, one might still have to gather data to find a next step to proceed.

I have two cases showing the need to combat "that's impossible", both from the same bug.

  • In this bug, a graphics processor appeared to be disappearing from the system's bus -- the CPU couldn't reach it while the program was executing. This usually took some 16 hours to reproduce, so as much data as possible needed to be extracted from each repro session. Unfortunately, we still had no indicators that the issue was about to recur at that point, so any data collection must have been done post-mortem. The first time we found a particularly interesting syndrome after reproducing the issue, we wanted more details about what had happened, but the system did not have a debug build of the driver.

    The standard assertion is that it's "impossible" to extract meaningful data from a driver's release build. Unfortunately, in this case, impossible simply wouldn't do; in order to make meaningful progress on this bug, we needed the data from this specific repro case. So, we started from basics -- we knew what was in the registers, and we knew that the data that we wanted was somewhere in memory, so we dug through data structures until we found an offset to the GPU's physical memory, and reconstructed our mental model of the machine's state from there.

  • We also had a piece of vendor code that we suspected of doing something specific to destabilize the system. We mentioned this to the vendor, who would not provide us with source (this binary contained other proprietary information). Again, one might assert that it is "impossible" to extract substantial knowledge about what a program does from only a binary; some time with objdump and grep made quick work of it. 3

In both of these cases, the word "impossible" was actually used to mean "infeasible". But as a problem gets more difficult, the requirements to judge something infeasible should go way up; extraordinary techniques and deeper dives into the innards of a system may be necessary to solve a problem.

Infeasibility is not the only usage of "that's impossible", though. The other family of "that's impossible" that one should note -- and question! -- is when an observed symptom doesn't match with one's mental model as to what could happen. This aligns closely with "that's funny": rather than rejecting a data point that seems like it could not happen, we should instead focus in on it as much as we can. Drilling down to the details of such misbehaviors increases the depth of our knowledge of a system.

Tricks and techniques

The above two phrases are the overarching things that I really wish I had paid more attention to in the past. However, there are also a few other tricks that I feel are worth mentioning.

Keep a notebook.

If you expect to be running lots of experiments to root cause something, keep a notebook. In fact, even if you don't expect to be running lots of experiments, keep a notebook! A notebook can help you keep track of where you've been, which is important in two ways -- it can help you avoid repeating yourself, and it can help you put pieces together when you get stuck.

Keeping a notebook also has the added benefit of forcing you to justify experiments and paths of thought -- when you're about to look into something, you get in the habit of writing down why you've done it. In turn, this means that you'll perform fewer 'useless' experiments; if you're not sure what to do next, instead of doing something unproductive to keep yourself occupied, you might instead end up looking at your old data to come up with a better course of action.

Collect syndromes.

If there's variance in how your problem manifests, sometimes it might be useful to let it reproduce a handful of times, and keep a collection of all the syndromes that you see. Are some syndromes more helpful to debug than others? Why is the variance there? What causes the variance? Sometimes, you'll see a syndrome that looks like a smoking gun -- in the case of a crash, the crash might occur while the incipient "bad thing" is still happening elsewhere on the system. The more differing data you have, the better you can form and eliminate hypotheses.

Tell a story.

A useful abstraction for debugging can be storytelling. In any hard problem, there are two stories to be told: what you believe should be happening, and what is happening. Each can be expressed as a series of steps; at some point, the steps diverge. The problem at hand, then, is to narrow down the divergent step; zone in on it, and pinpoint exactly what went wrong. This is why explaining issues to a coworker or friend -- even a nontechnical friend!1 -- is often instrumental in debugging, since it causes you to enumerate everything from the beginning. In a case of being truly stuck, you can even write the story down longhand in your notebook, forcing yourself to enumerate every detail.

Pick a plan.

Sometimes, a problem will come to a head, and it seems like the only hypotheses remaining are truly outlandish. The feeling remains: this can't be it! Unfortunately, we might have nothing better to work with. Luckily, plans of action in debugging that might be destructive are rare, so even if the root cause being traced seems like it can't exist, it can often make sense to go after it.

When you think you have an idea of what to do next, write it down, or say out loud, "My next step is as such, and from that, I expect to have conclusive evidence for such or for such." Such plans can help you interpret results, and can help you decide what you need to do next.

Work the problem.

When all else fails, in the immortal words of Gene Kranz, work the problem. Work from the ground up. Work from the top down. Work from the inside out, or the outside in. Work the problem. There are many ways of attacking a tough issue; try all of them. Above all, don't get buffaloed -- if it seems like it's going to take some doing to solve the problem, get doing! Gene Kranz said those words to his team when he had three astronauts stranded in orbit and no clue of what had gone wrong. His team did it: they worked through one of the toughest problems manned spaceflight has experienced, and came out victorious. Use everything at your disposal, and know that you're working towards one goal: a solution.

Concluding thoughts

Hard problems are hard because, well, they're not easy. This might seem obvious, but they require a qualitatively different skillset from the sorts of things that we use every day to deal with minor difficulties. Hard problems require perseverance. Hard problems require throwing every trick in the book at them. Hard problems require an intimate knowledge of the system in which they appear... and sometimes systems outside those, too. Hard problems require the people working with them to be at their best. In this article, I've presented a handful of pieces of advice that can help to develop a methodology for working problems like the toughest I've encountered.

I solicit your feedback -- was this helpful? Could I have been more clear in some places? Do you have other poignant examples? Let me know, or feel free to leave comments below.

joshua

Acknowledgements

I would like to thank Ben Wolf for his expert proofreading of this article. (He provided a handful of excellent stylistic suggestions, as well as a handful that I hardheadedly refused to take, so the remaining dysfluencies should be seen as my fault alone.) I would also like to thank Luke Chang, my manager during the time I wrote this article, for his understanding in helping me walk the fine line between providing detail and revealing our trade secrets.


  1. Indeed, maybe an inanimate object; beware, however, that there can be fierce debate as to whether a cardboard dog or a rubber duck is ideal for such debugging practices. 

  2. For more stories like this, the interested reader might find Gene Kranz's memoir, Failure Is Not an Option, to be fascinating additional reading. His book served as inspiration in part for this article. 

  3. Truly, extracting information about a program from a binary is not only possible, but it's regularly done. Reverse engineering is a field that employs many, and there is a lot of information about it out there! For folks not in that business, though, it can seem somewhat foreign as a concept for learning more about friendly binaries, instead of malware... 

SSTC2: PFC stage

NOTE FROM THE FUTURE, September 2025: When the winding wire on the inductor on the boost converter is thicker than the wire for the input, this is a good indication that you may have no idea what you are doing. I wonder what I will think about my current designs in 2038.

The power factor correction stage for SSTC2 was based on Texas Instruments's UCC28019 integrated PFC controller. (For the rationale behind the use of a PFC circuit, see the main page for SSTC2.) Much of the PFC circuit is what one might expect, but for the sake of completeness in documentation, this page contains our implementation notes. Included also are schematics, for one who may wish to replicate this build, and overall lessons learned in designing the system.

The PFC circuit's design parameters were for a target output power of 1.5kW, a target output voltage of 350V, and a target input range of 100~240V. We used, as mentioned, around 60 turns of 10 AWG flexible-stranded wire wrapped around a Micrometals T400-34D toroid; for the input capacitor, we chose ten 0.1µF ceramics in parallel, and for the output, we placed a 0.1µF ceramic near the diode to eat up the switching hash, and a 2-series-2-parallel network of film capacitors (for a total capacitance of 1.2µF) a ways further away to absorb the overall 60kHz ripple.

Our design generally was done by the book. For a switching MOSFET, we used a Fairchild FCA36N60NF, and for the boost rectifier, we used a Fairchild RURP3060, which are both certainly well sized for what we intended to do. (The FET is rated for 600V and 36A, whereas we will be loading it at maximum with 400V or so, and an RMS current of 12A; the diode is similarly oversized.)

The points of innovation, then, were primarily in assembly. The UCC28019's sample layout is designed for circuits handling somewhat lower power, and is best done with a printed circuit board; for ease of assembly and prototyping, though, we experimented with ways of putting this circuit together that didn't involve sending anything off to a board house.

Basic operating principles

Before diving too deeply into how we built our system, I should provide a quick overview for those readers unfamiliar with the basic operation of a power factor correction circuit. (Those who know already should feel free to skip this section.) Power factor, for those unfamiliar, is how much the current from the power mains is in phase with the voltage; since the voltage coming from the mains is sinusoidal, ideally the current would also be sinusoidal, proportional to the voltage. Circuits that simply charge a capacitor from the mains through a diode, however, have large current peaks as the input voltage transitions above where the output voltage has sagged to, and no current the rest of the time; so, those circuits have relatively poor power factor.

The power factor correction circuit is designed to avoid that by "forcing" current into the output throughout the line cycle. It does that through the basic mechanism of a boost converter -- a switch-mode power supply that converts a lower input voltage into a higher one. In the schematic at right, the switch periodically closes, causing current to ramp up through the inductor; once energy is stored in the inductor, the switch opens, and current flows through the diode into the load. The control circuit detects both the input voltage and the output voltage, and modulates the switch waveform to keep the output voltage at a reasonable level, and to keep the input current waveform in phase with the input voltage waveform.

For more on switch-mode power supplies, I suggest reading through the excellent smpstech.com, in addition to your favorite textbook (or your favorite online encyclopedia, as it may turn out). Dave Jones's EEVblog has an episode on power factor correction using the MC34262, which looks like a part designed for somewhat lower power.

Attempt 1: Red wires

The first iteration put the control logic on its own piece of perfboard, attaching the power components through something analogous to a Berg strip. This, actually, turned out to work pretty well; it increased maintainability and assemblability, since it meant that the thick wire portions were not inextricably linked to part that required many fiddle little connections between all the passives in the world.

To connect the power components, we first got a nicely sized heatsink from Halted Surplus, and screwed the parts in, using silpads and shoulder washers to isolate them all. We then placed some Kapton tape under the terminals, and used the left over 10ga wire from the boost inductor to connect each of the parts up.

From this, a few things were discovered. First, 10ga wire, even in extremely finely stranded form, is a bear to solder. It required feeding extreme amounts of solder (and extreme amounts of heat!) into it in order for the solder to permeate through, and connecting multiple pieces of 10ga on the same terminal (for instance, on the bridge rectifier) proved to be a pain. This vastly decreased the maintainability of the system in the event of a FET failure, and although the wire looked OK, the solder connections themselves did not always look great (often they looked 'cold', or otherwise did not have the solder bonding all of the strands together).

Second, having long lengths of wire causes undesirable electrical effects. The wires must have added a fair bit of inductance to the system, because quite a bit less than expected of the switching hash got eaten up by the capacitors. Further, they behaved as excellent antennae; the PFC circuit had very severe EMI problems, causing every active circuit nearby it to misbehave in new and exciting ways. (For instance, the connected bias power supply for the UCC28019 gave wildly swinging readings for voltage and current output on its front panel display; the connected El-Cheapo DMM on the output lit up the 'check battery' and 'I am now measuring frequency instead of voltage' indicators, and proceeded to spew random numerals on the screen; and the isolated (!) oscilloscope proceeded to trigger at any trigger setting even when no (!!!) inputs were connected.)

Beyond that, though, the circuit passed initial validation. It happily output 80W into a test load, and when the inputs and outputs had ferrites attached to them, circuits nearby no longer totally lost their minds. It made a concerning buzzing on startup (more on that later), but beyond the remaining EMI and component stress issues, it seemed to work.

Attempt 2: Dremel board

We decided in the end that the "red-wire" implementation wouldn't really be suitable; some issues that originally looked like instability (the gate waveform varying -- it turned out that that was the PFC doing its normal thing... hurr...) tipped us over the edge to finding a better way to attach the components together. Steve Conner suggested that a lot of the switching hash was from lead inductance, and that we should do our best to decouple the diode current loop (and to keep that loop as short as possible). In the shower, I thought of an elegant solution leveraging what we had the ability to do at home, and I went to Halted again that afternoon; I returned with some copper clad, and some new engraving bits for the Dremel.

I cut holes in the copper clad for where the leads looked like they should go, and then bent them up and poked them through the holes. I also cut holes for the screws in the parts, so if any part failed, I could simply unscrew everything, lift the board up, and change out the part. After some careful trial and error, I got all of the parts lined up; after poking them through, I used the engraving bit to make "anti-traces" around each circuit node.

This new layout has a few salient features. First, the output capacitance is much closer; second, the input capacitance is, too! Actually, basically everything is much closer, and that's a good thing, since it means that the diode current loop should be much smaller. The piece of copper clad is also held fairly well in place by a bunch of leads that are not very willing to bend; the effect is a piece of copper clad hovering some .5" off of a heat sink, making a very nice tight "power brick" package. I also added a 0.1µF ceramic capacitor decoupling the output much closer in, which neatly avoided the ESL of the photoflash caps far away, and the lead inductance of the film capacitors a distance out.

Results and performance

With this new setup, performance is pretty good. The system still sings on startup; we tracked that down to the piezoelectric effect taking place on the input ceramic capacitor bank. Even given that we fudged a handful of component values to meet with what we had lying around, the output voltage is basically 350V on the nose! Running a resistive 1500Ω load on the output, we had a power factor of 0.99; efficiency was around 85%, which is not too terrible for no load. You can watch a video of it operating here.

To measure various other characteristics of the circuit, we needed a storage scope; unfortunately, the storage scope I have (my beloved Tek 7623A) is not isolated, so another trip to Halted was taken, and I picked up a 250VA isolation transformer to run the circuit from.

Ringing on the gate, as you can see above, is not too bad. (Timescale looks to be about 1µs/div.) Rise and fall times are also pretty reasonable; in retrospect, we might have wanted to slow down the fall time some, to allow the diode to ramp up more cleanly!

Output noise and ripple are also pretty reasonable. A substantial spike shows up at the switching intervals, but ripple is within the expected tolerance -- around about 5V. (The connected probe is a 10x probe, AC coupled.) A fast storage shot might reveal a little more information about the noise burst, but we're not too worried as it stands.

Lessons learned

There are a few things that we did poorly in this that we wish we had changed. Probably chief among these is the fact that there is line voltage on the control board; the divider is on board with the control circuit, which means that in the event of a fault, potentially large currents could flow through the control cabling. This was mitigated some by having the divider circuit as close to the input connector as possible, but even still, it is something of an uncomfortable situation to have 350V right next to -0.4V on the control connector...

Similarly, if it had been more readily possible, it would have been nice to have other safety measures on the power board. For instance, a gate-source resistor would make plugging in the power supply without the control board (or the event of a control board fault!) less likely to blow up the FET; along the same lines, in the second revision, we had resistors onboard for the output, but in the first revision, the discharge resistors were a part of the load only.

The other important thing to note from this is that component choice matters. The whole system could have been a lot lighter if we had chosen a ferrite core, instead of a powdered iron core (though the saturation characteristics would have been quite a bit less favorable). For the input capacitor, based on availability, we chose to bundle together ten 0.1µF 500V ceramic capacitors to make one 1µF input capacitor, but this resulted in rather loud singing on startup. So, using film capacitors when able may make for better characteristics all around the circuit.

If we were to do it again, or to build more of these, it would probably be a good decision to put the control logic on the same board as the power parts, and to get the boards sent out for fabrication. I did like the way the heatsink meshed with the copper clad, though, so I would recommend that to others building this circuit.

We have not run the system up to full load yet, but I suspect that it should be able to handle that without major incident.

Schematics

Anyone wishing to build this might do well to look at the schematics for what we built:

These schematics were drawn in EAGLE, though drawn for readability, not for layout coordination. Let me know if you see any errors.

Before building this circuit, read all notes and read above descriptions! Important points are noted that may change your choices when building.

Solid State Tesla Coil, mk.II

Sometime in November of 2011, Chris Lu, Jacob Potter and I decided that we should have a good household project -- and what better of an idea than to build a successor to Chris's original PlasmaSonic II-driven Solid State Tesla Coil (SSTC)? So, we embarked on designing a coil under the parameter of being just a good, solid, durable SSTC. We weren't looking for the biggest TC out there (we couldn't power it), or to get the longest sparks, or the highest power, but just simply a nice solid simple SSTC.

We decided that our methodology would be to build a system that was more-or-less universal, so that we could design the drive circuitry without worrying about what we'd load it with; we not-so-fondly recalled the days of having to manually tweak pots for the best sparks, and blowing up FETs with a system that's out of tune, so we decided to design a system that would be self-tuning. We also wanted to be able to experiment with emulating the nice sword-like sparks that vacuum tube Tesla coils (VTTCs) made, so we decided to design to be able to actively wave-shape; as an added bonus, this would allow us to build an interrupter "for free", and also get audio modulation "for free".

On this page, I describe the basic design, and provide some level of added detail for the implementation.

If you're looking for something specific, try one of these links:

System design

We decided that for this system, we could easily separate the work into three stages: the power input stage, the wave-shaping stage, and the drive stage. Each of these can be more or less tested in isolation, and each can work independently; the design parameters for each stage is to work as part of the whole system, but in keeping with the design philosophy of a robust, durable system, they will also work in a wide range of other conditions.

Notable about this is that in some designs, only the drive stage actually exists; the power input stage may just be implemented as a bridge rectifier and capacitor tank, if even that. Similarly, the wave-shaping stage in many other designs seems to be just an interrupter (with the notable exception of more recent QCW DRSSTCs). In our setup, however, each stage is independently designed, and each is about equally complex; in a sense, though, we designed them to be almost elegant in how simple they can be for what they do.

Input stage: PFC

We chose a power factor correction boost circuit as a basic design for our input stage. The PFC circuit provides a few advantages:

  • Higher rail voltage. In the US, rectifying 120V mains will result in only 170V on the rails. SSTCs tend to perform better given higher voltage; the PFC design that we've chosen gives 350V on the rails (limited only by the expense of the switching components that we chose).
  • Better rail stability. A standard bridge rectifier / capacitor setup will result in quite a bit of cycle-to-cycle ripple. PFC circuits maintain at least some limited input into the capacitor throughout the line cycle, allowing for a smaller capacitor (and hence less energy stored to go into detonating a shorted FET).
  • And, of course, better power factor. Since we live in California, it seems only logical to have a green Tesla coil. Combined with a line filter, even though we'll be making plenty of RF noise nearby, we should at least manage to avoid sending too much noise upstream through the power lines.

We based the PFC circuit on the example appnote given in the datasheet for TI's UCC28019 integrated PFC controller part. TI, thankfully, provides an absolutely excellent component calculator in the form of an Excel spreadsheet; Apple's Numbers imported it without issue. Given the input and power parameters, the tool will calculate currents through most parts of the circuit, and given switching device parameters, the tool will calculate power dissipation, allowing a reasonable approximation at what sorts of parts will be needed. (It further calculates values of various passives in the control loop, making our job that much easier.)

For the boost inductor, we chose to use a powdered iron core for its preferential saturation characteristics -- no, actually, we chose it because I picked the first thing that someone on IRC mentioned. A ferrite core would perhaps have been better for this application, though this core gives us plenty of headroom if we want to go up in power. We used a Micrometals T400-34D toroid wound with some 60 turns of 10 AWG stranded wire. We discounted Litz wire first because of the small ripple current that we have (only about 6 Amps), and second because of the prohibitively expensive nature of it.

The final design allows for an input voltage of anywhere from 100 to 240V, and an output power of 350V at 4.3A-ish, or 1.5kW. (The actual output voltage will change a little bit with tolerances, but it should stay pretty well regulated.)

For more information on the PFC stage, see the page dedicated to it.

Wave-shaping stage: Class-D

Drive stage: PLL

Mechanics

Mechanically, not much novel was done in the construction of this coil. We used 26 AWG enameled magnet wire from McMaster, wound on 6" drain pipe from Lowe's, for the secondary. The secondary was coated with between 10 and 15 coats of Minwax Fast-Drying Polyurethane, as is standard for many coilers. The primary is composed of about 20 feet of 1/4"-diameter copper tubing on a conical form; it's held in place by six laser-cut acrylic supports. (The supports also hold the secondary in place.) The supports are solvent-welded to a polycarbonate base. The whole primary support feels sturdy; the secondary sits in the middle, and can be removed for easy transport or maintenance.

For more on the mechanical design, read the not-yet-written page on it.

Build log

This is presently somewhat out of date.

By December 27th, 2011, the PFC circuit had been built, but not tested. First powerup happened around the first of the new year; the circuit was rebuilt in the new configuration on the third or fourth, and the bias supply was integrated on the 7th. The PFC circuit is now operational, and has been tested up to a load of 85W or so.

On January 9th, 2012, the resonator was wound.

A few words about buggy sponsorship

This past weekend -- April 19th to 21st, 2012 -- I went back to Carnegie Mellon as an alum for Spring Carnival. I took a red-eye to get there, arriving at 0930 after a connection through Cleveland; I slept a total of one hour the night before. Arriving on campus at about 10:30-ish, I spent a moment in a cluster, and then around 11 or 11:30, I wandered off to one of the most hallowed traditions marking the start of Spring Carnival -- buggy design competition. By the time I made it back to Gates, it was around 1:30, and my body was starting to catch up with me. "Ah! I see what's happened here. I'm stumbling sleep-deprived across the Pausch Bridge under a too-bright sun on my way back from a buggy event." I knew I was back at Carnegie Mellon.

I saw everything I expected to see. There were teams there looking pretty with their buggies; there were teams there with everything on display; there were teams with nothing on display. (Well, there was team with nothing on display. But PiKA will be PiKA.) There were old staples of buggy; there were missing faces, like my beloved PiONEERS; and there were new teams (APEX, in the wake of PiONEERS, and DeltaForce, in the wake of DTD). Pervasive in design comp was the spirit of buggy as an unifying theme, though -- everyone had their own reasons for joining or forming their teams, but at the same time, none of them would have spent countless sleepless hours without buggy tying them all together.

Buggy is one of those few competitive sports that fosters at least some level of collaboration. Everyone wants to win, but everyone knows that sweepstakes can't survive without everyone playing fairly. When someone crashes in the chute, everyone is ready to help out, and do whatever it takes. When a small or struggling organization has a broken buggy, three different organizations will pitch in effort and manpower to help. When Bonsai spun in the women's heats on raceday, even the most diehard SDC alumni hoped that they'd have it fixed up in time for the men's heats; they knew what it was like to have a push team and a driver practicing all year just for that day.

The other side of buggy is that it's a uniquely Carnegie Mellon experience. "My heart is in the work" -- indeed! This is why I was shocked and saddened as an alum, then, to see corporate sponsorship plastered all about the course this year. I was not terribly impressed by the sponsor's products; but in my racedays past, I was always happy to see the SDC buggy at right, even if they weren't my favorite team. When raceday was invaded this year by Chrysler, though, I felt like the sport had been compromised; in addition to the banners simply being an eyesore on the course, one of the most prized elements of Sweepstakes is that teams are never allowed to accept corporate sponsorship.


I present, then, a counterpoint in four images.

When a buggy crosses the finish line, everybody knows it isn't really over. The buggy has to pass a handful of safety checks, generally referred to as "drops". Drops take place on one side of the course, and are televised; a failure there can DQ the fastest lap of the day! This year, we were provided with a Jeep banner to watch instead.

Hamerschlag always stands guard, making sure that no cars can intercept buggies heading up past Scaife. This year, instead of barricades, Chrysler placed a large tent for all to see.

Buggy has always been a sport of fitting small people into small vehicles, and a game of ruthless efficiency. This year, Chrysler showed off a vehicle that was "easier to get into than CMU", and a small car that managed an embarrassing 30mpg (premium gasoline required).

Buggy is traditionally set against the scenic backdrop of Carnegie Mellon and Schenley Park, which can actually look quite pretty on a sunny day like this one. This year, Chrysler decided that the beauty was theirs.


My question, then -- whose sport is this, anyway? Carnegie Mellon has a rich history in Sweepstakes; there may be room in it for tasteful sponsorship, perhaps, but this wasn't it.

Joshua Wise
April 26, 2012

The Coming War on General Computation

The Coming War on General Computation

Presented at 28C3 by Cory Doctorow doctorow@craphound.com.

Transcribed by Joshua Wise joshua@joshuawise.com.

This transcription attempts to be faithful to the original, but disfluencies have generally been removed (except where they appear to contribute to the text). Some words may have been mangled by the transcription; feel free to submit pull requests to correct them!

Times are always marked in #double square brackets.

The original content was licensed under Creative Commons CC-BY (http://boingboing.net/2011/12/30/transcript-of-my-28c3-keynote.html); this transcript is more free, as permitted. You may provide me transcript attribution if you like, or if it does not make sense given the context, you can simply give Cory Doctorow original author attribution.

The canonical source for this is on GitHub, here.

Christian Wöhrl has submitted a translation of this text into German.

Júlio Garcia has submitted a translation of this text into Portuguese.

Transcript

Introducer:

Anyway, I believe I've killed enough time ... so, ladies and gentlemen, a person who in this crowd needs absolutely no introduction, Cory Doctorow!

[Audience applauds.]

Doctorow:

#27.0 Thank you.

#32.0 So, when I speak in places where the first language of the nation is not English, there is a disclaimer and an apology, because I'm one of nature's fast talkers. When I was at the United Nations at the World Intellectual Property Organization, I was known as the "scourge" of the simultaneous translation corps; I would stand up and speak, and turn around, and there would be window after window of translator, and every one of them would be doing this [Doctorow facepalms]. [Audience laughs] So in advance, I give you permission when I start talking quickly to do this [Doctorow makes SOS motion] and I will slow down.

#74.1 So, tonight's talk -- wah, wah, waaah [Doctorow makes 'fail horn' sound, apparently in response to audience making SOS motion; audience laughs]] -- tonight's talk is not a copyright talk. I do copyright talks all the time; questions about culture and creativity are interesting enough, but to be honest, I'm quite sick of them. If you want to hear freelancer writers like me bang on about what's happening to the way we earn our living, by all means, go and find one of the many talks I've done on this subject on YouTube. But, tonight, I want to talk about something more important -- I want to talk about general purpose computers.

Because general purpose computers are, in fact, astounding -- so astounding that our society is still struggling to come to grips with them: to figure out what they're for, to figure out how to accommodate them, and how to cope with them. Which, unfortunately, brings me back to copyright.

#133.8 Because the general shape of the copyright wars and the lessons they can teach us about the upcoming fights over the destiny of the general purpose computer are important. In the beginning, we had packaged software, and the attendant industry, and we had sneakernet. So, we had floppy disks in ziplock bags, or in cardboard boxes, hung on pegs in shops, and sold like candy bars and magazines. And they were eminently susceptible to duplication, and so they were duplicated quickly, and widely, and this was to the great chagrin of people who made and sold software.

#172.6 Enter DRM 0.96. They started to introduce physical defects to the disks or started to insist on other physical indicia which the software could check for -- dongles, hidden sectors, challenge/response protocols that required that you had physical possession of large, unwieldy manuals that were difficult to copy, and of course these failed, for two reasons. First, they were commercially unpopular, of course, because they reduced the usefulness of the software to the legitimate purchasers, while leaving the people who took the software without paying for it untouched. The legitimate purchasers resented the non-functionality of their backups, they hated the loss of scarce ports to the authentication dongles, and they resented the inconvenience of having to transport large manuals when they wanted to run their software. And second, these didn't stop pirates, who found it trivial to patch the software and bypass authentication. Typically, the way that happened is some expert who had possession of technology and expertise of equivalent sophistication to the software vendor itself, would reverse engineer the software and release cracked versions that quickly became widely circulated. While this kind of expertise and technology sounded highly specialized, it really wasn't; figuring out what recalcitrant programs were doing, and routing around the defects in shitty floppy disk media were both core skills for computer programmers, and were even more so in the era of fragile floppy disks and the rough-and-ready early days of software development. Anti-copying strategies only became more fraught as networks spread; once we had BBSes, online services, USENET newsgroups, and mailing lists, the expertise of people who figured out how to defeat these authentication systems could be packaged up in software as little crack files, or, as the network capacity increased, the cracked disk images or executables themselves could be spread on their own.

#296.4 Which gave us DRM 1.0. By 1996, it became clear to everyone in the halls of power that there was something important about to happen. We were about to have an information economy, whatever the hell that was. They assumed it meant an economy where we bought and sold information. Now, information technology makes things efficient, so imagine the markets that an information economy would have. You could buy a book for a day, you could sell the right to watch the movie for one Euro, and then you could rent out the pause button at one penny per second. You could sell movies for one price in one country, and another price in another, and so on, and so on; the fantasies of those days were a little like a boring science fiction adaptation of the Old Testament book of Numbers, a kind of tedious enumeration of every permutation of things people do with information and the ways we could charge them for it.

#355.5 But none of this would be possible unless we could control how people use their computers and the files we transfer to them. After all, it was well and good to talk about selling someone the 24 hour right to a video, or the right to move music onto an iPod, but not the right to move music from the iPod onto another device, but how the Hell could you do that once you'd given them the file? In order to do that, to make this work, you needed to figure out how to stop computers from running certain programs and inspecting certain files and processes. For example, you could encrypt the file, and then require the user to run a program that only unlocked the file under certain circumstances.

#395.8 But as they say on the Internet, "now you have two problems". You also, now, have to stop the user from saving the file while it's in the clear, and you have to stop the user from figuring out where the unlocking program stores its keys, because if the user finds the keys, she'll just decrypt the file and throw away that stupid player app.

#416.6 And now you have three problems [audience laughs], because now you have to stop the users who figure out how to render the file in the clear from sharing it with other users, and now you've got four! problems, because now you have to stop the users who figure out how to extract secrets from unlocking programs from telling other users how to do it too, and now you've got five! problems, because now you have to stop users who figure out how to extract secrets from unlocking programs from telling other users what the secrets were!

#442.0 That's a lot of problems. But by 1996, we had a solution. We had the WIPO Copyright Treaty, passed by the United Nations World Intellectual Property Organization, which created laws that made it illegal to extract secrets from unlocking programs, and it created laws that made it illegal to extract media cleartexts from the unlocking programs while they were running, and it created laws that made it illegal to tell people how to extract secrets from unlocking programs, and created laws that made it illegal to host copyrighted works and secrets and all with a handy streamlined process that let you remove stuff from the Internet without having to screw around with lawyers, and judges, and all that crap. And with that, illegal copying ended forever [audience laughs very hard, applauds], the information economy blossomed into a beautiful flower that brought prosperity to the whole wide world; as they say on the aircraft carriers, "Mission Accomplished". [audience laughs]

#511.0 Well, of course that's not how the story ends because pretty much anyone who understood computers and networks understood that while these laws would create more problems than they could possibly solve; after all, these were laws that made it illegal to look inside your computer when it was running certain programs, they made it illegal to tell people what you found when you looked inside your computer, they made it easy to censor material on the internet without having to prove that anything wrong had happened; in short, they made unrealistic demands on reality and reality did not oblige them. After all, copying only got easier following the passage of these laws -- copying will only ever get easier! Here, 2011, this is as hard as copying will get! Your grandchildren will turn to you around the Christmas table and say "Tell me again, Grandpa, tell me again, Grandma, about when it was hard to copy things in 2011, when you couldn't get a drive the size of your fingernail that could hold every song ever recorded, every movie ever made, every word ever spoken, every picture ever taken, everything, and transfer it in such a short period of time you didn't even notice it was doing it, tell us again when it was so stupidly hard to copy things back in 2011". And so, reality asserted itself, and everyone had a good laugh over how funny our misconceptions were when we entered the 21st century, and then a lasting peace was reached with freedom and prosperity for all. [audience chuckles]

#593.5 Well, not really. Because, like the nursery rhyme lady who swallows a spider to catch a fly, and has to swallow a bird to catch the spider, and a cat to catch the bird, and so on, so must a regulation that has broad general appeal but is disastrous in its implementation beget a new regulation aimed at shoring up the failure of the old one. Now, it's tempting to stop the story here and conclude that the problem is that lawmakers are either clueless or evil, or possibly evilly clueless, and just leave it there, which is not a very satisfying place to go, because it's fundamentally a counsel of despair; it suggests that our problems cannot be solved for so long as stupidity and evilness are present in the halls of power, which is to say they will never be solved. But I have another theory about what's happened.

#644.4 It's not that regulators don't understand information technology, because it should be possible to be a non-expert and still make a good law! M.P.s and Congressmen and so on are elected to represent districts and people, not disciplines and issues. We don't have a Member of Parliament for biochemistry, and we don't have a Senator from the great state of urban planning, and we don't have an M.E.P. from child welfare. (But perhaps we should.) And yet those people who are experts in policy and politics, not technical disciplines, nevertheless, often do manage to pass good rules that make sense, and that's because government relies on heuristics -- rules of thumbs about how to balance expert input from different sides of an issue.

#686.3 But information technology confounds these heuristics -- it kicks the crap out of them -- in one important way, and this is it. One important test of whether or not a regulation is fit for a purpose is first, of course, whether it will work, but second of all, whether or not in the course of doing its work, it will have lots of effects on everything else. If I wanted Congress to write, or Parliament to write, or the E.U. to regulate a wheel, it's unlikely I'd succeed. If I turned up and said "well, everyone knows that wheels are good and right, but have you noticed that every single bank robber has four wheels on his car when he drives away from the bank robbery? Can't we do something about this?", the answer would of course be "no". Because we don't know how to make a wheel that is still generally useful for legitimate wheel applications but useless to bad guys. And we can all see that the general benefits of wheels are so profound that we'd be foolish to risk them in a foolish errand to stop bank robberies by changing wheels. Even if there were an /epidemic/ of bank robberies, even if society were on the verge of collapse thanks to bank robberies, no-one would think that wheels were the right place to start solving our problems.

#762.0 But. If I were to show up in that same body to say that I had absolute proof that hands-free phones were making cars dangerous, and I said, "I would like you to pass a law that says it's illegal to put a hands-free phone in a car", the regulator might say "Yeah, I'd take your point, we'd do that". And we might disagree about whether or not this is a good idea, or whether or not my evidence made sense, but very few of us would say "well, once you take the hands-free phones out of the car, they stop being cars". We understand that we can keep cars cars even if we remove features from them. Cars are special purpose, at least in comparison to wheels, and all that the addition of a hands-free phone does is add one more feature to an already-specialized technology. In fact, there's that heuristic that we can apply here -- special-purpose technologies are complex. And you can remove features from them without doing fundamental disfiguring violence to their underlying utility.

#816.5 This rule of thumb serves regulators well, by and large, but it is rendered null and void by the general-purpose computer and the general-purpose network -- the PC and the Internet. Because if you think of computer software as a feature, that is a computer with spreadsheets running on it has a spreadsheet feature, and one that's running World of Warcraft has an MMORPG feature, then this heuristic leads you to think that you could reasonably say, "make me a computer that doesn't run spreadsheets", and that it would be no more of an attack on computing than "make me a car without a hands-free phone" is an attack on cars. And if you think of protocols and sites as features of the network, then saying "fix the Internet so that it doesn't run BitTorrent", or "fix the Internet so that thepiratebay.org no longer resolves", then it sounds a lot like "change the sound of busy signals", or "take that pizzeria on the corner off the phone network", and not like an attack on the fundamental principles of internetworking.

#870.5 Not realizing that this rule of thumb that works for cars and for houses and for every other substantial area of technological regulation fails for the Internet does not make you evil and it does not make you an ignoramus. It just makes you part of that vast majority of the world for whom ideas like "Turing complete" and "end-to-end" are meaningless. So, our regulators go off, and they blithely pass these laws, and they become part of the reality of our technological world. There are suddenly numbers that we aren't allowed to write down on the Internet, programs we're not allowed to publish, and all it takes to make legitimate material disappear from the Internet is to say "that? That infringes copyright." It fails to attain the actual goal of the regulation; it doesn't stop people from violating copyright, but it bears a kind of superficial resemblance to copyright enforcement -- it satisfies the security syllogism: "something must be done, I am doing something, something has been done." And thus any failures that arise can be blamed on the idea that the regulation doesn't go far enough, rather than the idea that it was flawed from the outset.

#931.2 This kind of superficial resemblance and underlying divergence happens in other engineering contexts. I've a friend who was once a senior executive at a big consumer packaged goods company who told me about what happened when the marketing department told the engineers that they'd thought up a great idea for detergent: from now on, they were going to make detergent that made your clothes newer every time you washed them! Well after the engineers had tried unsuccessfully to convey the concept of "entropy" to the marketing department [audience laughs], they arrived at another solution -- "solution" -- they'd develop a detergent that used enzymes that attacked loose fiber ends, the kind that you get with broken fibers that make your clothes look old. So every time you washed your clothes in the detergent, they would look newer. But that was because the detergent was literally digesting your clothes! Using it would literally cause your clothes to dissolve in the washing machine! This was the opposite of making clothes newer; instead, you were artificially aging your clothes every time you washed them, and as the user, the more you deployed the "solution", the more drastic your measures had to be to keep your clothes up to date -- you actually had to go buy new clothes because the old ones fell apart.

#1012.5 So today we have marketing departments who say things like "we don't need computers, we need... appliances. Make me a computer that doesn't run every program, just a program that does this specialized task, like streaming audio, or routing packets, or playing Xbox games, and make sure it doesn't run programs that I haven't authorized that might undermine our profits". And on the surface, this seems like a reasonable idea -- just a program that does one specialized task -- after all, we can put an electric motor in a blender, and we can install a motor in a dishwasher, and we don't worry if it's still possible to run a dishwashing program in a blender. But that's not what we do when we turn a computer into an appliance. We're not making a computer that runs only the "appliance" app; we're making a computer that can run every program, but which uses some combination of rootkits, spyware, and code-signing to prevent the user from knowing which processes are running, from installing her own software, and from terminating processes that she doesn't want. In other words, an appliance is not a stripped-down computer -- it is a fully functional computer with spyware on it out of the box.

[audience applauds loudly] Thanks.

#1090.5 Because we don't know how to build the general purpose computer that is capable of running any program we can compile except for some program that we don't like, or that we prohibit by law, or that loses us money. The closest approximation that we have to this is a computer with spyware -- a computer on which remote parties set policies without the computer user's knowledge, over the objection of the computer's owner. And so it is that digital rights management always converges on malware.

#1118.9 There was, of course, this famous incident, a kind of gift to people who have this hypothesis, in which Sony loaded covert rootkit installers on 6 million audio CDs, which secretly executed programs that watched for attempts to read the sound files on CDs, and terminated them, and which also hid the rootkit's existence by causing the kernel to lie about which processes were running, and which files were present on the drive. But it's not the only example; just recently, Nintendo shipped the 3DS, which opportunistically updates its firmware, and does an integrity check to make sure that you haven't altered the old firmware in any way, and if it detects signs of tampering, it bricks itself.

#1158.8 Human rights activists have raised alarms over U-EFI, the new PC bootloader, which restricts your computer so it runs signed operating systems, noting that repressive governments will likely withhold signatures from OSes unless they have covert surveillance operations.

#1175.5 And on the network side, attempts to make a network that can't be used for copyright infringement always converges with the surveillance measures that we know from repressive governments. So, SOPA, the U.S. Stop Online Piracy Act, bans tools like DNSSec because they can be used to defeat DNS blocking measures. And it blocks tools like Tor, because they can be used to circumvent IP blocking measures. In fact, the proponents of SOPA, the Motion Picture Association of America, circulated a memo, citing research that SOPA would probably work, because it uses the same measures as are used in Syria, China, and Uzbekistan, and they argued that these measures are effective in those countries, and so they would work in America, too!

[audience laughs and applauds] Don't applaud me, applaud the MPAA!

#1221.5 Now, it may seem like SOPA is the end game in a long fight over copyright, and the Internet, and it may seem like if we defeat SOPA, we'll be well on our way to securing the freedom of PCs and networks. But as I said at the beginning of this talk, this isn't about copyright, because the copyright wars are just the 0.9 beta version of the long coming war on computation. The entertainment industry were just the first belligerents in this coming century-long conflict. We tend to think of them as particularly successful -- after all, here is SOPA, trembling on the verge of passage, and breaking the internet on this fundamental level in the name of preserving Top 40 music, reality TV shows, and Ashton Kutcher movies! [laughs, scattered applause]

#1270.2 But the reality is, copyright legislation gets as far as it does precisely because it's not taken seriously, which is why on one hand, Canada has had Parliament after Parliament introduce one stupid copyright bill after another, but on the other hand, Parliament after Parliament has failed to actually vote on the bill. It's why we got SOPA, a bill composed of pure stupid, pieced together molecule-by-molecule, into a kind of "Stupidite 250", which is normally only found in the heart of newborn star, and it's why these rushed-through SOPA hearings had to be adjourned midway through the Christmas break, so that lawmakers could get into a real vicious nationally-infamous debate over an important issue, unemployment insurance. It's why the World Intellectual Property Organization is gulled time and again into enacting crazed, pig-ignorant copyright proposals because when the nations of the world send their U.N. missions to Geneva, they send water experts, not copyright experts; they send health experts, not copyright experts; they send agriculture experts, not copyright experts, because copyright is just not important to pretty much everyone! [applause]

#1350.3 Canada's Parliament didn't vote on its copyright bills because, of all the things that Canada needs to do, fixing copyright ranks well below health emergencies on First Nations reservations, exploiting the oil patch in Alberta, interceding in sectarian resentments among French- and English-speakers, solving resources crises in the nation's fisheries, and thousand other issues! The triviality of copyright tells you that when other sectors of the economy start to evince concerns about the Internet and the PC, that copyright will be revealed for a minor skirmish, and not a war. Why would other sectors nurse grudges against computers? Well, because the world we live in today is /made/ of computers. We don't have cars anymore, we have computers we ride in; we don't have airplanes anymore, we have flying Solaris boxes with a big bucketful of SCADA controllers [laughter]; a 3D printer is not a device, it's a peripheral, and it only works connected to a computer; a radio is no longer a crystal, it's a general-purpose computer with a fast ADC and a fast DAC and some software.

#1418.9 The grievances that arose from unauthorized copying are trivial, when compared to the calls for action that our new computer-embroidered reality will create. Think of radio for a minute. The entire basis for radio regulation up until today was based on the idea that the properties of a radio are fixed at the time of manufacture, and can't be easily altered. You can't just flip a switch on your baby monitor, and turn it into something that interferes with air traffic control signals. But powerful software-defined radios can change from baby monitor to emergency services dispatcher to air traffic controller just by loading and executing different software, which is why the first time the American telecoms regulator (the FCC) considered what would happen when we put SDRs in the field, they asked for comment on whether it should mandate that all software-defined radios should be embedded in trusted computing machines. Ultimately, whether every PC should be locked, so that the programs they run are strictly regulated by central authorities.

#1477.9 And even this is a shadow of what is to come. After all, this was the year in which we saw the debut of open sourced shape files for converting AR-15s to full automatic. This was the year of crowd-funded open-sourced hardware for gene sequencing. And while 3D printing will give rise to plenty of trivial complaints, there will be judges in the American South and Mullahs in Iran who will lose their minds over people in their jurisdiction printing out sex toys. [guffaw from audience] The trajectory of 3D printing will most certainly raise real grievances, from solid state meth labs, to ceramic knives.

#1516.0 And it doesn't take a science fiction writer to understand why regulators might be nervous about the user-modifiable firmware on self-driving cars, or limiting interoperability for aviation controllers, or the kind of thing you could do with bio-scale assemblers and sequencers. Imagine what will happen the day that Monsanto determines that it's really... really... important to make sure that computers can't execute programs that cause specialized peripherals to output organisms that eat their lunch... literally. Regardless of whether you think these are real problems or merely hysterical fears, they are nevertheless the province of lobbies and interest groups that are far more influential than Hollywood and big content are on their best days, and every one of them will arrive at the same place -- "can't you just make us a general purpose computer that runs all the programs, except the ones that scare and anger us? Can't you just make us an Internet that transmits any message over any protocol between any two points, unless it upsets us?"

#1576.3 And personally, I can see that there will be programs that run on general purpose computers and peripherals that will even freak me out. So I can believe that people who advocate for limiting general purpose computers will find receptive audience for their positions. But just as we saw with the copyright wars, banning certain instructions, or protocols, or messages, will be wholly ineffective as a means of prevention and remedy; and as we saw in the copyright wars, all attempts at controlling PCs will converge on rootkits; all attempts at controlling the Internet will converge on surveillance and censorship, which is why all this stuff matters. Because we've spent the last 10+ years as a body sending our best players out to fight what we thought was the final boss at the end of the game, but it turns out it's just been the mini-boss at the end of the level, and the stakes are only going to get higher.

#1627.8 As a member of the Walkman generation, I have made peace with the fact that I will require a hearing aid long before I die, and of course, it won't be a hearing aid, it will be a computer I put in my body. So when I get into a car -- a computer I put my body into -- with my hearing aid -- a computer I put inside my body -- I want to know that these technologies are not designed to keep secrets from me, and to prevent me from terminating processes on them that work against my interests. [vigorous applause from audience] Thank you.

#1669.4 Thank you. So, last year, the Lower Merion School District, in a middle-class, affluent suburb of Philadelphia found itself in a great deal of trouble, because it was caught distributing PCs to its students, equipped with rootkits that allowed for remote covert surveillance through the computer's camera and network connection. It transpired that they had been photographing students thousands of times, at home and at school, awake and asleep, dressed and naked. Meanwhile, the latest generation of lawful intercept technology can covertly operate cameras, mics, and GPSes on PCs, tablets, and mobile devices.

#1705.0 Freedom in the future will require us to have the capacity to monitor our devices and set meaningful policy on them, to examine and terminate the processes that run on them, to maintain them as honest servants to our will, and not as traitors and spies working for criminals, thugs, and control freaks. And we haven't lost yet, but we have to win the copyright wars to keep the Internet and the PC free and open. Because these are the materiel in the wars that are to come, we won't be able to fight on without them. And I know this sounds like a counsel of despair, but as I said, these are early days. We have been fighting the mini-boss, and that means that great challenges are yet to come, but like all good level designers, fate has sent us a soft target to train ourselves on -- we have a organizations that fight for them -- EFF, Bits of Freedom, EDRi, CCC, Netzpolitik, La Quadrature du Net, and all the others, who are thankfully, too numerous to name here -- we may yet win the battle, and secure the ammunition we'll need for the war.

#1778.9 Thank you.

[sustained applause]

Kerberized NFSv4 HOWTO

This page is a running documentation page for setting up Kerberized NFSv4. As I set up my network (and I guess in some cases after I set up my network ...), I'll document what I'm doing so that other people don't have to go through this mess again later. This page is a work in progress.

Why Kerberized NFSv4?

Words to the effect of:

  • Initially wanted setup between nyus and home network
  • nyus lives a fair ways off on the network (over untrusted terrain, anyway)
  • NFSv3 not working out so well; Kerberos supported or not supported depending on who you ask
  • NFSv3 requires RO export hacks (see link 1), and did not want to export RO to the world

Steps:

  • JOSHUAWISE.COM does not have a Kerberos realm yet
  • Set up a Kerberos realm
  • Test it by Kerberizing SSH
  • Try setting up NFS
  • Kerberize client?

Setting up a client

This assumes that you've already set up a Kerberos realm and that you've already also set up your NFS server. As usual, I'll be using the Kerberos realm JOSHUAWISE.COM for testing, and I'll be using the server nyus.joshuawise.com. I'll be setting up the client on shebang.

  • Verify that kernel has NFSv4 support.
joshua@shebang:/usr/src/linux-2.6.17.7$ grep nfs4 /proc/filesystems
nodev   nfs4
  • Install krb5 stuff. You may do different things depending on your distro.
joshua@shebang:~$ sudo apt-get install krb5-clients krb5-user krb5-doc krb5-config
words

Prompt shows up: Enter the hostnames of Kerberos servers in the JOSHUAWISE.COM Kerberos realm separated by spaces. How the heck did it know that this is the JOSHUAWISE.COM realm?? I put in kerberos.joshuawise.com, which is a CNAME for joshuawise.com, which is my KDC. I put in kerberos.joshuawise.com for the administrative server, too. Dumped me back to a prompt.

  • Verify that the realm is set up properly in /etc/krb5.conf:
[libdefaults]
        default_realm = JOSHUAWISE.COM

Add in the a setting for my realm in the [domain_realm] section:

        joshuawise.com = JOSHUAWISE.COM
        .joshuawise.com = JOSHUAWISE.COM
  • Try kinit'ing:
joshua@shebang:~$ kinit
Password for joshua@JOSHUAWISE.COM:
joshua@shebang:~$
  • Make a directory for nyus:
joshua@shebang:~$ sudo mkdir /nfs/nyus
  • Try mounting it to see what I did wrong: (this seemed too damn easy!)
joshua@shebang:~$ sudo mount -t nfs4 -o sec=krb5i,rw nyus.joshuawise.com:/ /nfs/nyus
Warning: rpc.idmapd appears not to be running.
         All uids will be mapped to the nobody uid.
mount: wrong fs type, bad option, bad superblock on nyus.joshuawise.com:/,
       missing codepage or other error
       In some cases useful info is found in syslog - try
       dmesg | tail  or so
  • Turn on idmapd and gssd. Edit /etc/default/nfs-common and change the variable set lines that are currently empty so that they look like this:
# Do you want to start the idmapd daemon? It is only needed for NFSv4.
NEED_IDMAPD=yes

# Do you want to start the gssd daemon? It is required for Kerberos mounts.
NEED_GSSD=yes
  • Make those settings take effect:
joshua@shebang:~$ sudo /etc/init.d/nfs-common restart
  • Try mounting again:
joshua@shebang:~$ sudo mount -t nfs4 -o sec=krb5i,rw nyus.joshuawise.com:/ /nfs/nyus
mount: block device nyus.joshuawise.com:/ is write-protected, mounting read-only
mount: cannot mount block device nyus.joshuawise.com:/ read-only

WARNING! WARNING! WARNING! mount IS LYING! IGNORE ITS LIES! THEY SERVE ONLY TO CONFUSE YOU! "write-protected", especially when followed by "cannot mount read-only", really means "the mount failed when I tried to mount it read-write for an unspecified reason", not that it is actually write-protected. Take a look in syslog to see what the issue was:

Jan 21 22:16:17 shebang rpc.gssd[6676]: ERROR: No such file or directory while beginning keytab scan for keytab '/etc/krb5.keytab'
Jan 21 22:16:17 shebang rpc.gssd[6676]: ERROR: No usable keytab entries found in keytab '/etc/krb5.keytab'
Jan 21 22:16:17 shebang rpc.gssd[6676]: Do you have a valid keytab entry for nfs/<your.host>@<YOUR.REALM> in keytab file /etc/krb5.keytab ?
Jan 21 22:16:17 shebang rpc.gssd[6676]: Continuing without (machine) credentials - nfs4 mounts with Kerberos will fail
Jan 21 22:17:34 shebang rpc.gssd[6676]: WARNING: Failed to obtain machine credentials for connection to server NYUS.RES.cmu.edu
Jan 21 22:17:34 shebang rpc.gssd[6676]: WARNING: Failed to obtain machine credentials for connection to server NYUS.RES.cmu.edu
  • Two issues here. Issue one -- no keytab. Resolve this by kadminning up and getting the NFS key for nyus.
joshua@shebang:~$ sudo kadmin
Authenticating as principal root/admin@JOSHUAWISE.COM with password.
Password for root/admin@JOSHUAWISE.COM: <type my password here>
kadmin:  ktadd nfs/nyus.joshuawise.com
Entry for principal nfs/nyus.joshuawise.com with kvno 4, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal nfs/nyus.joshuawise.com with kvno 4, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/etc/krb5.keytab.
kadmin:  ^Djoshua@shebang:~$

If you get issues here to the effect of:

kadmin: Operation requires ``change-password'' privilege while changing nfs/nyus.joshuawise.com@JOSHUAWISE.COM's key

then you have not restarted the Kerberos admin server after adding the */admin * ACL. This can be frustratingly difficult to discover, especially when you thought you restarted it earlier after setting that the first time around, and you thought that anyway it should've discovered it by now, and what is it doing changing a key anyway -- shouldn't it be just adding it to the keytab?, and you're still not certain that that's what are supposed to do there, and ... Well, you get the picture. * Restart gssd. /etc/init.d/nfs-common restart * Issue two -- NYUS.RES.cmu.edu != nyus.joshuawise.com. Add to /etc/hosts:

128.2.162.192 nyus.joshuawise.com
  • Retry the mount:
joshua@shebang:~$ sudo mount -t nfs4 -o sec=krb5i,rw nyus.joshuawise.com:/ /nfs/nyus
mount: Connection timed out

Now what's wrong?!... shebang is behind NAT, but who cares? dmesg reports:

[17341332.176000] RPC: AUTH_GSS upcall timed out.
[17341332.176000] Please check user daemon is running!

OK, so I restarted rpc.gssd using rpc.gssd -vvvf, and got this:

joshua@shebang:~$ sudo mount -t nfs4 -o sec=krb5i,rw nyus.joshuawise.com:/ /nfs/nyus
handling krb5 upcall
Using keytab file '/etc/krb5.keytab'
INFO: Credentials in CC 'FILE:/tmp/krb5cc_machine_JOSHUAWISE.COM' are good until 1169473613
using FILE:/tmp/krb5cc_machine_JOSHUAWISE.COM as credentials cache for machine creds
using environment variable to select krb5 ccache FILE:/tmp/krb5cc_machine_JOSHUAWISE.COM
creating context using fsuid 0 (save_uid 0)
creating tcp client for server nyus.joshuawise.com
creating context with server nfs@nyus.joshuawise.com

long pause...

WARNING: Failed to create krb5 context for user with uid 0 for server nyus.joshuawise.com
WARNING: Failed to create krb5 context for user with uid 0 with credentials cache FILE:/tmp/krb5cc_machine_JOSHUAWISE.COM for server nyus.joshuawise.com
WARNING: Failed to create krb5 context for user with uid 0 with any credentials cache for server nyus.joshuawise.com
doing error downcall
destroying client clnt12
mount: block device nyus.joshuawise.com:/ is write-protected, mounting read-only

Note: It appears that rpc.gssd died because I control-c'ed a mount. After I restarted rpc.gssd again, I got some new messages in addition to the old ones:

handling krb5 upcall
WARNING: failed reading uid from krb5 upcall pipe: No such file or directory
WARNING: can't create tcp rpc_clnt for server nyus.joshuawise.com for user with uid 0: RPC: Remote system error - Connection timed out

OK, well, I should've checked nyus's syslog:

Jan 21 23:37:04 localhost rpc.svcgssd[8000]: WARNING: gss_accept_sec_context failed
Jan 21 23:37:04 localhost rpc.svcgssd[8000]: ERROR: GSS-API: error in handle_nullreq: gss_accept_sec_context(): Miscellaneous failure - Key version number for principal in key table is incorrect
Jan 21 23:37:04 localhost rpc.svcgssd[8000]: WARNING: failed to write message
  • Verify and fix key versions. A key version, evidently, is also known as a "kvno". When I did the "ktadd" on shebang, it incremented the kvno, which meant that shebang had the only up to date principal! When I did the ktadd again on nyus to update it, of course, I just broke shebang and dashnine. To prove that this is how it broke, I can do this:
joshua@shebang:~$ sudo klist -e -k -t /etc/krb5.keytab
Keytab name: FILE:/etc/krb5.keytab
KVNO Timestamp         Principal
---- ----------------- --------------------------------------------------------
   4 01/21/07 22:24:33 nfs/nyus.joshuawise.com@JOSHUAWISE.COM (Triple DES cbc mode with HMAC/sha1)
   4 01/21/07 22:24:33 nfs/nyus.joshuawise.com@JOSHUAWISE.COM (DES cbc mode with CRC-32)
joshua@shebang:~$ sudo kadmin
Authenticating as principal root/admin@JOSHUAWISE.COM with password.
Password for root/admin@JOSHUAWISE.COM:
kadmin:  getprinc nfs/nyus.joshuawise.com@JOSHUAWISE.COM
Principal: nfs/nyus.joshuawise.com@JOSHUAWISE.COM
<blah blah>
Number of keys: 2
Key: vno 7, Triple DES cbc mode with HMAC/sha1, no salt
Key: vno 7, DES cbc mode with CRC-32, no salt

I just ended up ktremove'ing the nyus keys from shebang, and ktadding to get the latest on nyus. * Make a keytab on shebang. I tturns out that I didn't need nyus's key on shebang, I just needed some key. So, I did this:

joshua@shebang:~$ sudo kadmin
Authenticating as principal root/admin@JOSHUAWISE.COM with password.
Password for root/admin@JOSHUAWISE.COM:
kadmin:  addprinc -randkey host/shebang.joshuawise.com
WARNING: no policy specified for host/shebang.joshuawise.com@JOSHUAWISE.COM; defaulting to no policy
Principal "host/shebang.joshuawise.com@JOSHUAWISE.COM" created.
kadmin:  addprinc -randkey nfs/shebang.joshuawise.com
WARNING: no policy specified for nfs/shebang.joshuawise.com@JOSHUAWISE.COM; defaulting to no policy
Principal "nfs/shebang.joshuawise.com@JOSHUAWISE.COM" created.
kadmin:  ktadd host/shebang.joshuawise.com
Entry for principal host/shebang.joshuawise.com with kvno 3, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/shebang.joshuawise.com with kvno 3, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/etc/krb5.keytab.
kadmin:  ktadd nfs/shebang.joshuawise.com
Entry for principal nfs/shebang.joshuawise.com with kvno 3, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal nfs/shebang.joshuawise.com with kvno 3, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/etc/krb5.keytab.
kadmin:  ^Djoshua@shebang:~$
  • Restart gssd to use the new keytab.
joshua@shebang:~$ sudo killall rpc.gssd
joshua@shebang:~$ sudo killall rpc.gssd
rpc.gssd: no process killed
joshua@shebang:~$ sudo rpc.gssd
joshua@shebang:~$
  • Mount nyus.
joshua@shebang:~$ sudo mount -t nfs4 -o sec=krb5i,rw nyus.joshuawise.com:/ /nfs/nyus
joshua@shebang:~$
  • Test the security of Kerberized NFS.
joshua@shebang:~$ kinit
Password for joshua@JOSHUAWISE.COM:
joshua@shebang:~$ ls /nfs/nyus
bin  boot  dev  etc  home  initrd  initrd.img  lib  lost+found  media  mnt  nfs  opt  proc  root  sbin  srv  sys  tmp  usr  var  vmlinuz
joshua@shebang:~$ touch /nfs/nyus/foo
touch: cannot touch `/nfs/nyus/foo': Permission denied
joshua@shebang:~$ touch /nfs/nyus/home/joshua/foo
joshua@shebang:~$ sudo rm /nfs/nyus/home/joshua/foo # because root has not authenticated as joshua
rm: remove write-protected regular empty file `/nfs/nyus/home/joshua/foo'? y
rm: cannot remove `/nfs/nyus/home/joshua/foo': Permission denied
joshua@shebang:~$ rm /nfs/nyus/home/joshua/foo
joshua@shebang:~$
  • Add nyus to /etc/fstab:
nyus.joshuawise.com:/ /nfs/nyus nfs4    user,exec,rsize=8192,wsize=8192,intr,rw,sec=krb5i       0   0

...and give it a shot...

joshua@shebang:~$ kdestroy
joshua@shebang:~$ sudo umount /nfs/nyus
joshua@shebang:~$ mount /nfs/nyus
joshua@shebang:~$ ls /nfs/nyus
ls: /nfs/nyus: Permission denied
joshua@shebang:~$ kinit
Password for joshua@JOSHUAWISE.COM:
joshua@shebang:~$ ls /nfs/nyus
bin  boot  dev  etc  home  initrd  initrd.img  lib  lost+found  media  mnt  nfs  opt  proc  root  sbin  srv  sys  tmp  usr  var  vmlinuz
joshua@shebang:~$ kdestroy
joshua@shebang:~$ ls /nfs/nyus
bin  boot  dev  etc  home  initrd  initrd.img  lib  lost+found  media  mnt  nfs  opt  proc  root  sbin  srv  sys  tmp  usr  var  vmlinuz
  • Presto! A mostly working Kerberized NFSv4 setup, in only 19 mind-bogglingly overcomplicated steps! There, now that wasn't so bad, was it?

Setting up PAM

Mode notes:

  • Install pam_krb5: joshua@nyus:~$ sudo apt-get install libpam-krb5
  • Add pam_krb5 to /etc/pam.d/common-auth as first line: auth sufficient pam_krb5.so ignore_root
  • Add pam_krb5 to /etc/pam.d/common-session as first line: session optional pam_krb5.so ignore_root
  • Add pam_krb5 to /etc/pam.d/common-account as first line: account required pam_krb5.so ignore_root
  • Add pam_krb5 to /etc/pam.d/common-password as first line: password optional pam_krb5.so ignore_root
  • Move away allowed keys to force a password login: joshua@nyus:~/.ssh$ mv authorized_keys2 authorized_keys2-old
  • Change password to something that is not my UNIX password: joshua@shebang:~$ kpasswd
  • Try connecting: joshua@shebang:~$ ssh nyus
  • Observe that it uses the new Kerberos password.
  • Change the password using PAM passwd: joshua@nyus:~$ passwd
  • Connect again and observe that the password has been changed.
  • Observe that 'klist' shows that you have a TGT after logging in over SSH using the PAM module.
  • You now have working pam_krb5. passwd is a little messy:
joshua@nyus:~/.ssh$ passwd
Password:
Changing password for joshua
(current) UNIX password:
Enter new password:
Enter it again:
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully

Here's some stuff I've referenced while setting this system up.

Defeating HP's Wireless Whitelist for Fun and Profit

Chris Lu and I originally wrote -- and did -- this around December, 2005. The article has been preserved for posterity. New since then is Tiido Priimägi's version of this hack, which takes it to another level; see below!

As the authors of this article discovered unintentionally, recent HP laptops (including the HP tc1100 tablet PC and the HP zv5460us desktop replacement) have a wireless whitelist built into the BIOS similar to that found by Matthew Garrett on IBM Thinkpads. In an attempt to replace the built in Broadcom wireless card in Chris' laptop with an Atheros card, we came across this evil firmware hack on our own. In this paper, we will detail the method that we used to defeat this lockout.

Brain Damaged Lockouts -- A Little Bit of Theory

When the PC was first designed, it was designed on the premise of expandibility. Architectures were standardized for the express purpose of creating a platform that anybody (well, anybody with the time and money to do so) could build on top of. As time went on, the platform became more versatile -- computational power increased, electrical power consumption decreased, size decreased, and expansions that nobody would've even conceived of sprang into existance. The computer market thrived on competition between multiple manufacturers who wanted to provide an expansion that did the same thing.

But over time, computers tended towards becoming more integrated machines -- black boxes, if you will. Consumers began looking for one box that they could buy that did everything that they needed. With this trend, manufacturers began shipping inferior parts with computers because they could get away with it. Sure, the user could go out later and buy a more powerful replacement, but they had still given their money to the original manufacturer for the less powerful part. The industry continued to thrive, offering upgrades for users who wanted them.

Recently, though, manufacturers have started down a worryingly slippery slope. Parts that have otherwise been commodities -- in particular, wireless cards -- have been arbitrarly decided to be "incompatible" with machines that they would otherwise be electrically and computationally compatible with. We found that out the hard way when Chris bought a more powerful wireless card for his laptop. He eagerly installed it in his system, but when he powered the system on, he was greeted with an error: "104 - Unsupported wireless device. System halted."

The system powered up, and found that a wireless card existed. However, it determined that it was not a wireless card that was "approved" by the system, and hence refused to allow access to any part of the system until the "unapproved" device was removed. We saw this as an affront to the history on which these computers were developed, and began searching for a way to circumvent this restriction.

Hacking the BIOS? Buy It Optional Service

The card that we wished to insert into this system was an Atheros-based wireless card that did not have the appropriate bits set to have the HP BIOS recognize it. In the past, we tried modifying the BIOS as mentioned on Garrett's site, however our success was limited. We managed to complete all steps from 1 to 5; however the latter part of the 6th step unfortunately applied. (To quote: "your laptop is probably dead".) After the BIOS reflash, the system refused to power up, instead spinning all of its fans at full throttle. When the system was returned from service, we decided not to attempt that modification again, and try for other routes. However, while the system was in service, we decided to think up other methods to defeat the lockout.

PCI: Proof of Concept Initialization

In the days after sending in the the zv5460us for repair, the authors tried out other methods on Joshua's HP tc1100, which suffers from the same whitelist lockout. We had read elsewhere that other people had success with suspending the system before the kernel boots, inserting the wireless card, and resuming the system and allowing the kernel to boot. The tc1100 cannot suspend without help from an operating system - it especially cannot suspend when at the GRUB menu. However, luckily for us, the tc1100 has some level of suspend and resume support under Linux, as long as no graphics drivers are loaded.

We booted the tc1100 into a single user mode and forced the system into a "suspend-to-RAM" state. Since power was removed from the PCI bus, we were able to successfully insert the card into the tc1100 without causing the system to release smoke. When we resumed the system, there were no BIOS errors, but the card was not recognized. We used an application called "kexec" to boot a new instance of Linux without going through the BIOS. When the new instance reprobed for PCI devices, it successfully found the card on the bus, and loaded the drivers.

Obviously, this is too unwieldy for daily use. Although the card functions in the end, the system must be disassembled at every boot. However, we had successfully completed an initial proof of concept - PCI can be initialized without help from the BIOS.

Extrapolating

When the zv5460us came back, one question that came up was whether we could hotplug the mini-PCI board to avoid the BIOS seeing it. We decided that this would be too risky. In addition to putting the bus in an inconsistent state for a few milliseconds, we also determined that we'd run the risk of applying signal voltage before applying power, and hence putting the chip into a latchup state and destroying the board. We decided that this risk was unacceptable - after all, the goal is to make the board work, not to destroy the board.

While continuing to think of ways to have the board disappear during the BIOS board detect process, Joshua drew on prior knowledge of the PCI bus to think of disabling the board's configuration selection enable pin (IDSEL) while the BIOS was probing. This would prevent the BIOS from detecting the card and complaining.

For those of you unfamiliar with the internals of the PCI bus, on boot, the system needs to scan all of the slots on the system for cards before it can assign them "addresses" to be called on. On the PCI bus, all of the signals are shared with the exception of the pin that requests a card to identify itself at system boot time. (This pin is called "IDSEL".) So, on boot, the system "asks" each card in the system what it is by raising the IDSEL signal on each pin and sending a brief sequence of commands. The system then parses the results, assigns resources to the cards if necessary, and possibly complains that you are using a disallowed card. However, if a slot does not respond (usually because there is no card in that slot), the system does not bother to interrogate further -- it just moves on. This scanning process is what we needed to defeat -- we wanted to cause the BIOS to move on instead of recognizing that our (unauthorized) Atheros PCI card is in the system.

IDSEL Part 1: It's Disabled; Selection Emerges Later

After some time on Google, we determined that the Mini-PCI card that we're looking at is "type III". After a little more time, we found the pinouts for these sorts of card. Looking down on the left side of the chart, we see that IDSEL is pin 48. However, this is entirely useless without knowing how the pin numbers are assigned.

We first tried linearly going from left to right on the component side of the board (i.e., the side of the board facing up in the system). We painstakingly counted out 48 pins, placed some Scotch tape over the offending pin, and used an Exacto knife to remove the excess. We placed the freshly-modified wireless card in the system and powered up. The system booted, but when we used the "lspci" command to see what cards were in the system, a card that was not our wireless card and was not anything else that the system knew about appeared. The identification bits appeared to be similar to the wireless card's, but one particular bit was cleared. Evidently the pin that we masked was a pin that carried data, not the IDSEL pin that we were looking for.

We also tried a few other permutations, including starting on the bottom, starting on the right top, and starting on the right bottom. Unfortunately, none of those worked. Just as we were about to give up, we got one more idea -- and we had a way to test it.

One of the signatures that we could use to determine whether we had the pins correct on the card without masking a pin and inserting into the system was the pattern of grounds. We could do a continuity check between the metal shield on the card and the pins that we believe to be ground on the card, and get an audible indication as to whether our hypothesis was correct. We briefly tested this by running through the pin orders that we knew to be incorrect, and sure enough, the grounds were not where we expected them.

At that point, we found some information on the web that led us to believe that the pins alternated on the card edge header - for example, pin 1 is on the left side of the component side; pin 2 is immediately under pin 1; pin 3 is to the right of pin 1; pin 4 is immediatly under pin 3; and so on. We decided to test this one more pattern before looking for a new pin-out. It turned out, in fact, that the grounds were in the right place using that method.

We cut out a piece of tape to cover pin 48 with (which we found to be immediately to the left of two grounds on top of each other, making it very easy to recognize), and inserted it into Chris' system. Much to our surprise, the system successfully booted, and the card was not detected by Linux -- exactly in line with our expectations for a disabled IDSEL pin.

IDSEL Part 2: I Defeated System-Enforced Lockouts

Now that we have successfully disabled IDSEL temporarily, we need to be able to control it so that it's enabled when Linux wants to see it. The plan of attack in this case will be to cut the IDSEL trace on the Mini-PCI board, and to install a normally-closed switch in its place.

On our board, there was a clearly defined trace running on the solder side of the board from the IDSEL trace to a via. This was as ideal as it gets -- the trace was in plain sight, and fairly decently far away from other traces (no worries about cutting more traces than we expected), and we had two nice size pads to solder our wire to.

We used an exacto blade that we actuated by hand to cut the trace. It took substantially more force and effort than one might've expected for such a thin line. Still, after a while, we successfully sawed through it. To free up the via to solder to, we put the tip of the knife in the middle and lightly turned it around to remove some of the solder mask. Once enough of a pad was made accessible to solder to, we cut and stripped a piece of 30ga wire, and tacked it down with a SMD soldering tip. We did a similar thing to the physical IDSEL pin on the card-edge connector. Finally, when the connections tested to be proper, we placed a small dot of hot glue on to to keep them in place. On the other ends of the 30ga wire, we soldered on a normally-closed switch, to be depressed on boot time.

It was then the moment of truth -- time to insert the card. Chris inserted the freshly-modified card into his system and powered it up while holding down the switch. Sure enough, the system booted to a GRUB prompt, at which point he released the switch. GRUB proceeded to load Linux, which happily detected the MADWiFi drivers, associated with a nearby access point, and got an IP address -- mission accomplished.

Future plans

The majority of this experiment was performed over the course of three hours. Our goal was to keep this project as simple as possible for the time being, and add more features later if need be. We anticipate a few problems, however, when we scale this design up.

First, the leads that we used on our implementation were fairly short - on the order of 4 inches each. We anticipate the possibility of signal integrity problems as we increase the length of the leads. The solution to that that comes to mind is to avoid sending the signal through the switch - instead, have the switch control the base on a transistor that diverts IDSEL to ground.

It's still a little unwieldy to need to hold down the switch while booting the system, so one might wish to build an automation module that causes the device to "disappear" for some time on reset. One way to do that might be to use a R-C timer, a buffer, and a diode to sink the signal on power-on until the BIOS has completed running. It should also be noted that the LED pins are different on the official HP cards, so the wireless activity light on the keyboard did not illuminate when the card was in use. Perhaps some more 30ga wire could be used to make the light useful again.

In the end, we shouldn't have needed to go to these measures to upgrade the wireless card in the system. Perhaps the best solution would be not to buy another laptop from a manufacturer that implements such draconian restrictions in their firmware; indeed, that seems like the only way to convince HP to change their policies.

DIY: Don't It Yourself

As we mentioned previously, the traces on the boards are extremely small, as are the pads to solder to. If you aren't intimately familiar with electronic designs, and in particular, soldering, we recommend that you do not attempt this. This procedure could result in the wireless card, the Mini-PCI slot, or the entire machine ceasing to function. We can not take any responsibility for damages that you might incur while attempting this procedure.

Photos

Other Implementations

Tiido Priimägi sent me e-mail to say that he did it too. He, on the other hand, did it with the aforementioned RC timer. He first hacked a card in that way:

He then decided that the next step is generalized it, so he decided to rip the mPCI connector off of his laptop and replace it with a taller one so that he could hide all the circuitry under the card and inside the machine.

Substantial kudos to Tiido for an extremely gutsy rework.

Donate Life

If you know me, you know that there are some things that I really really feel strongly about. There aren't a whole lot of them, but they exist, which makes them even more special. This is one of those things.

I suppose I should introduce my dad for those of you who don't really know me. It really started around 1995 when I was about four or five years old. Some years before, my dad had been diagnosed with Hepatitis C, a liver disease that can and will kill if left untreated. At this point in time, however, the disease started becoming a bigger and bigger issue looming over us. I had just begun to comprehend the magnitude of the disease, and the possible consequences. My dad was getting sicker and sicker. He was reduced to sleeping for the majority of the day, a massive change from a man who used to run miles in the mornings. Needless to say, it was scary. However, hope was in our eyes. Around that time, he was near number one on the list for a liver transplant. For those unfamiliar with the idea, a transplant would remove his liver that had been so badly damaged by the disease, and give him a new liver that hopefully is compatible with his body. Any number of things can go wrong, but meanwhile, the disease got worse by the day.

To make a long story short, that liver didn't quite work out. His body was not able to adjust to that particular liver, due to some factor that we do not know about at this point in time. After many more years of stress, he made his way back up the list for another liver. This was a big deal. We lucked out big time. Twice. Through some combination of miracles, excellent doctors, and general modern wonders, he is still alive today, which we are all thankful for.

Unfortunately, there are lots of other people who aren't quite so lucky. Many people don't survive the time it takes for whatever organ they need to become available. Right now, there are about 110,500 people waiting on the list for transplantation. Every day, about 20 people across the United States die waiting for an organ. On average, every 11 minutes, somebody else gets added to the list.

The numbers are pretty grim, but there's a way to make a difference. Talk to the people around you, including your family members, and other people close to you. Talk to them about donating your organs in the event of your death. After reading this, I hope that you'll see why it really is that important. If you have any questions about organ donation, you might find the organdonor.gov Frequently Asked Questions to be helpful. And once you've discussed it with your folks and you've chosen to give others the gift of life later on, you can sign up in your state's donor registry.

Thank you for taking the time to read this. If you have any questions, or if you just want more information, please don't hesitate to get in touch with me! You can find my contact information here.

Joshua Wise, 2004-05-23

Epilogue 2007-06-10: On March 2nd, 2005, Jeffrey Wise passed away. His disease finally weakened his system to the point that his liver could no longer effectively filter blood, and the rest of his body progressively deteriorated. At 4:40pm, his body shut down fully. Goodbye, Dad.