Tag: Software freedom

Initial Developer Documentation for the Librem 5 Phone Platform

At Purism, we are just as excited as you are about the the development boards that will be distributed this summer. Once a person receives their development board, their first thought will be “This is great! Now, what do I do with it?” In anticipation of the technical guidance that will be needed, the developer documentation effort has begun. You can already see the current state of the documentation at developer.puri.sm

Goal of the Docs

The developer documentation is there as a guide for getting a new developer setup and ready to start having fun! This will include plenty of examples that will help you along towards whatever your goal with the development board may be.

There will be technical step-by-step instructions that are suitable for both newbies and experienced Debian developers alike. The goal of the docs is to openly welcome you and light your path along the way with examples and links to external documentation. These examples will aid you from the start of unpacking your development board to building and deploying flatpak applications to it—and eventually including your package into PureOS. Included, you can expect examples on how to use certain tools like flatpak, the IDEs used to build flatpak applications, and UI tools to help you design apps. The design of the Librem 5 phone interface will also be outlined in detail to provide insight into the human interface guidelines that will be followed by the core applications. Use the design section to learn about gestures you can expect on the phone. Apps you design or port to the board can use these gestures too!

Please note that the docs are not a complete tutorial on how to use all of the development tools required. There are existing documentations available for each specific tool so there’s no need to reinvent the wheel. Instead, you will be directed to those locations online so you can research further on a specific tool.

We welcome all test and development efforts that volunteers have to give, so there will also be information on volunteering and how to become a Purism community member in general.

Work in progress

The documentation is in a constant state of flux. Content is being added daily and reorganization still occurs from time-to-time. If you no longer see a page there, just search for it because chances are it has been moved to somewhere else within the site instead of removed. The aim is to write documentation that is helpful and intuitive so it is important that an intuitive path is laid out. This developer documentation is still pretty new but is filling out quickly so that you are ready to hit the ground running with your new development board in June!

There will be a separate announcement in the next few weeks on this same blog to call for volunteers so get ready!

Purism Integrates Trammel Hudson’s Heads security firmware with Trusted Platform Module, giving full control and digital privacy to laptop users

Librem devices add tamper-evident features to further protect users from cybersecurity threats by offering users the full control that no mainstream computer manufacturer ever has before

SAN FRANCISCO, Calif., February 27, 2018 — Purism, maker of security-focused laptops has announced today that they have successfully tested integration of Trammel Hudson’s Heads security firmware into their Trusted Platform Module (TPM)-enabled coreboot-running Librem laptops. This integration allows Librem laptop users to freely inspect the code, build and install it (and customize it) themselves, and own control of the secure boot process as Heads uses the TPM on the system to provide tamper-evidence. Read more

Librem 5 Phone Progress Report

Back from FOSDEM

Being at FOSDEM 2018 was a blast! We received a lot of great feedback about what we have accomplished and what we aim to achieve.  These sorts of constructive critiques from our community are how we grow and thrive so thank you so much for this! It helps us to focus our development. Moreover, I was very impressed by the appreciation that we received from the free software community. I know that relationships between companies, even Social Purpose Corporations—like Purism, and the free software communities are a delicate balance. You need to find a good balance between being transparent, open, and free on one side but also having revenue to sustain the development on the other side. The positive feedback we received at FOSDEM and the appreciation that was expressed for our projects was great to hear.

We are working really hard on making ethical products, based on free/libre and open source software a reality. This is not “just a job” for anybody on the Purism staff, we all love what we do and deeply believe in the good cause we are working so hard to achieve. Your appreciation and feedback is the fuel that drives us to work on it even harder. Thank you so much!

Software Work

As I mentioned before, we have the i.MX 6 QuadPlus test hardware on hand, so here are some photos of our development board actually running something:

On the right, you can see the Nitrogen board with the modem card installed. On the left is our display running a browser displaying the Purism web-page and below it a terminal window in which I started the browser. To put the resolution of the display into perspective I put a Micro SD card on the display:

Click to enlarge

The terminal window is about as big as three Micro SD cards! This makes it very clear that a lot of work has to be put into making applications usable on a high resolution screen and to make them finger friendly since the only input system we have is the touch screen. In the next picture I put an Euro coin on the screen and switched back to text console:

Click to enlarge

Concerning the software, we are working on getting the basic framework to work with the hardware we have at hand. One essential piece is the middleware that handles the mobile modem that deals with making phone calls and sending and receiving SMS text messages. For this we want to bring up oFono since it is also used by KDE Plasma mobile. We have a first success to share:

This is the first SMS sent through oFono from the iMX board and the attached modem to a regular mobile smartphone where the screenshot was taken. So we are on the right track here and have a solution that is starting to work that suits multiple possible systems, like Plasma mobile or a future GNOME/GTK+ based mobile environment.

The SMS was sent with a python script using the native oFono DBus API. First the kernel drivers for the modem had to be enabled followed by running ofonod which autodetects the modem. Next the modem must be enabled and brought online (online-modem). Once this was done sending an SMS was as simple as:

purism@pureos:~/ofono/test$ sudo ./send-sms 07XXXXXXXXX "Sent from my Librem 5 i.MX6 dev board!"

The script itself is very simple and instructive. Simulating the reception of a text message can also be done, with a command such as this one:

purism@pureos:~/ofono/test$ sudo ./receive-smsb 'Sent to my Librem 5 i.MX6 dev board!' LocalSentTime = 2018-02-07T10:26:19+0000 SentTime = 2018-02-07T10:26:19+0000 Sender = +447XXXXXXXXX


The evolution of mobile hardware manufacturing

We are building a phone, so hardware is an important part of the process. In our last blog post we talked a bit about researching hardware manufacturing partners. Since we are not building yet-another Qualcomm SOC based phone, but starting from scratch, we are working to narrow down all the design choices and fabrication partners in the coming months. This additional research phase has everything to do with how the mobile phone hardware market has evolved in the past years and I want to share how this all works with you.

In the early days of smartphones, a common case was that the main CPU was separated from the cellular baseband modem and that the cellular modem would run its own firmware when implementing all of the necessary protocols that operate the radio interface—at first it was GSM, then UMTS (3G) and finally LTE (4G). These protocols and the handling of the radio interface have become so complex that the necessary computational power for handling this as well as the firmware sizes have grown over time. Current 3G/4G modems include a firmware of 60 or more megabytes are becoming more common. It did not take long before storing this firmware became an issue as well as at run time since this requires significant increases of RAM usage.

Smartphones usually have a second CPU core for the main operating system which also runs the phone applications and interacts with the users. This means that your device must have two RAM systems as well, one for the baseband and one for the host CPU. This also means you need two storages for firmware, one for the host CPU and one for the baseband. As you may imagine, getting all of these components working together in a form factor small enough to fit into someone’s hand takes a lot of development and manufacturing resources.

The advent of cheap smartphones

There is extreme pressure about the cost of smartphones. In today’s commodity market, we see simple smartphones starting at prices less than $100 USD.

The introduction of combined chips, with radio baseband plus host CPU on one silicon die inside one chip, massively reduced costs. This allows the host CPU and baseband to share RAM and storage. Since the radio can be made in the same silicon process as the host CPU, and both can be placed in a single chip package, we see substantial cost reduction in the semiconductor manufacturing as well as the cost of manufacturing the device. This saves you from having to use a second large chip for the radio itself, an extra flash chip for its firmware, and possibly an extra RAM chip for its operation. This does not only reduce the Bill of Materials (BOM), but also PCB space, and it enables the creation of even smaller and thinner devices. Today we see many big companies offer these types of combined chipsets—such as Qualcomm, Broadcom, and Mediatek to name a few.

These chips caused a big shift in the mobile baseband modem market. Formerly it was common to find discrete baseband modems on the market that were applicable for mobile battery powered handsets like the one we are developing. But since the rise of the combined chipsets, the need for separated modems has dropped to a level that does not justify their development as much. You can still find modem modules and cards but these modules are usually targeted for M2M (machine to machine) communication with only limited data rates and most of them do not have audio/voice functions. They usually come in pretty large cards, such as the miniPCIe or M.2. For us this means that our choice of separated baseband modems suitable for a phone is narrowed.

What this means for OEM, ODM or Build it Yourself

All of this consolidation has an impact on hardware manufacturers and our choices. Pretty much all current smartphone designs by OEM/ODM manufacturers are based on the combined chipset types; this is all they know and it is where they have expertise. Almost no one is making phones with separated basebands anymore, and the ones who do are not OEMs nor ODMs. The options are further limited by our requirement not to include any proprietary firmware on our host CPU (which we wrote about before): most fabricators are unfamiliar with i.MX 6 or i.MX 8 and do not want to risk a development based on it, which narrows our hardware design and manufacturing partners to a much smaller list.

However, we have some promising partners that we will continue to evaluate, and we are confident that we are going to be able to design and manufacture the Librem 5 as we originally specified. We just wanted to share with you why making this particular hardware is so challenging and why our team is the best one to execute on this design. To continue to discuss with some of the manufacturers and providers, Purism will visit Embedded World, one of the world’s largest embedded electronics trade shows, in Nürnberg (Germany) in the beginning of March. And, as usual, we will continue to keep you updated on our progress!

Good news with our existing evaluation boards

We have been patiently waiting for the i.MX 8M to become available, all according to the forecast timeline from NXP. In the meantime, we have started developing software using the i.MX 6 QuadPlus board from Boundary Devices, specifically the NITROGEN6_MAX (Nit6Qp_MAX) since it is the closest we get to production devices before NXP releases the i.MX 8M. We have a Debian Testing based image running as a testbed on these boards while the PureOS team is preparing to build PureOS for ARM and ARM64 in special.

On these evaluation boards we have all the interfaces that we need for software development:

  1. Wi-Fi
  2. Video input and output
  3. USB for input devices
  4. Serial console and a miniPCIe socket with SIM card connected for attaching a mobile modem
  5. At the moment, we are using a Sierra Wireless MC7455 LTE miniPCIe modem card for development, which uses a Qualcomm MDM9230 baseband modem chip. This card is basically a USB device in a mPCIe form factor, i.e. we do not actually use the PCIe interface.
  6. An extremely nice display to our kits using an HDMI-to-MIPI adapter board. The display is a 5.5″ AMOLED display with full-HD resolution with the native orientation as portrait mode.

This hardware setup allows us to start a lot of the software development work now to ensure our development continues in parallel until we have the i.MX 8M based hardware in hand.

Next on our to-do list: phone calls!

Librem 5 Phone Progress Report

The Librem 5 and recent industry news

Lately, news headlines have been packed with discussions about critical CPU bugs which are not only found in Intel CPUs, but also partially in AMD CPUs and some ARM cores. At the same time, some of our backers have voiced concerns about the future of NXP in light of a potential acquisition by Qualcomm. Therefore you might be wondering, “Will the Librem 5 be affected by these bugs too?” and “will the Purism team get the i.MX 8 chips as planned?”, so let’s address those questions now.

Not affected by Spectre/Meltdown

At the moment we are pretty confident that we will be using one of NXP’s new i.MX 8 family of CPUs/SOCs for the Librem 5 phone. More specifically we are looking at the i.MX 8M which features four ARM Cortex A53 cores. According to ARM, these cores are not affected by the issues now known as Spectre or Meltdown, which ARM’s announcement summarizes in their security update bulletin.

So for the moment we are pretty sure that the Librem 5 phone will not be affected, however we will continue to keep an eye on the situation since more information about these bugs is surfacing regularly. In this respect we can also happily report that we have a new consultant assisting our team in security questions concerning hardware-aided security as well as questions like “is the phone’s CPU affected by Spectre/Meltdown or not”.

Qualcomm possibly buying NXP: not a concern

For quite some time there have been rumors that Qualcomm might have an interest in acquiring NXP. Since we will be using an NXP chip as the main CPU, specifically one of the i.MX 8 family, we are well aware of this development and are watching it closely.

Qualcomm is an industry leader for high volume consumer electronics whereas NXP targets lower volume industrial customers. This results in pretty different approaches concerning support, especially for free software. Where NXP traditionally is pretty open with specifications, Qualcomm is rather hard to get information from. This is very well reflected by the Linux kernel support for the respective chips. The question is how would it affect continued free software support and availability of information on NXP SOCs if Qualcomm acquires NXP?

First, it is unlikely that this deal will happen at all. Qualcomm had a pretty bad financial year in 2017 so they might not be in the financial position to buy another company. Second, there is a rumor that Broadcom might acquire Qualcomm first. Third, international monopoly control organizations are still investigating if they can allow such a merger at all. Just a few days ago the EU monopoly control agreed to allow the merge but with substantial constraints, for example Qualcomm would have to license several patents free of charge, etc. Finally, there are industry obligations that NXP cannot drop easily: the way NXP works with small and medium sized customers is a cornerstone of many products and customers; changing this would severely hamper all of those businesses involved, and these changes might cause bad reputation, bad marketing and loss of market share.

So all in all, this merger is not really likely to happen soon and there would probably not be changes for existing products like the i.MX 8 family. If the merger happens it might affect future/unreleased products.

Development outreach

In addition to working on obtaining i.MX6QuadPlus development boards to be able to work properly, the phone team is also intensively researching and evaluating software that we will base our development efforts on during the next few months. We are well aware of the huge amount of work ahead of us and the great responsibility that we have committed to. As part of this research, we reached out to the GNOME human interface design team with whom we began discussions on design as well as implementation. For example, we started to implement a proof of concept widget that would make it much easier to adapt existing desktop applications to a phone or even other style of user interface. What we would like to achieve is a convergence of devices so that a single application can adapt to the user interface it is currently being used with. This is still a long way ahead of us, but we are working on it now. We will meet up also with some GNOME team members at FOSDEM to discuss possible development and design goals as well as collaboration possibilities.

The mobile development work for KDE/Plasma will primarily be performed by their own human interface teams. Purism will be supporting their efforts through supplying hardware and documentation about our phone development progress as it is happening. This will help ensure that that KDE/Plasma will function properly on the Librem 5 right from the factory. To understand better where we’re headed with GNOME and KDE together, take a look at this blog post.

We also reviewed and evaluated compositing managers and desktop shells that we could use for a phone UI. We aim to use only Wayland, trying to get rid of as much X11 legacy as we possibly can, for performance issues and for better security. From our discussions with GNOME maintainers of existing compositors and shells, we may be better off igniting a new compositor (upstreamed and backed by GNOME) in order to avoid the X11 baggage.

On the application and middleware side of things, we have generated an impressive list of applications we could start to modify for the phone to reach the campaign goals and we have further narrowed down middleware stacks. We are still evaluating so I do not want to go into too much detail here, in order not set any expectation. We will of course talk about this in more detail in some later blog posts.

Meeting with Chip Makers

As the CPU choice is pretty clear lately, we are going to have a meeting with NXP and some other chip makers at Embedded World in Nürnberg, Germany, at the end of the month. This is very encouraging since we worked for months on getting a direct contact to NXP, which we now finally have and who we will meet in person at the conference. The search for design and manufacturing partners is taking longer than expected though. Our own hardware engineering team together with the software team, especially our low level and kernel engineers, started to create a hardware BOM (bill of material) and also a “floor plan” for a potential PCB (printed circuit board) layout, but it turns out that many manufacturers are reluctant to work with the i.MX 8M since it is a new CPU/SOC. We have, however, some promising leads and good contacts so we will work on that.

Purism Librem 5 team members attending FOSDEM

By the way, many Purism staff members will be at FOSDEM this week-end, on the 3rd and 4th of February. In addition to the design and marketing team, PureOS and Librem 5 team members will be there and we would love to get in touch with you! Purism representatives dedicated to answering your questions will be wearing this polo shirt so you can easily recognize them:

GNOME and KDE in PureOS: diversity across devices

PureOS, a Free Software Foundation endorsed GNU distribution, is what Purism pre-installs on all Librem laptops (in addition to it being freely available for the public to run on their own compatible hardware or virtual machines). It comes with a GNOME desktop environment by default, and of course, since we love free ethical software, users can use KDE that is also available within PureOS. This is the future we will continue to advance across all our devices: a PureOS GNOME-first strategy, with other Desktop Environments (DEs), such as KDE, available and supported by Purism.

At Purism we want a unified default desktop environment, and considering that we have chosen GNOME to be the default on laptops, we hope to extend GNOME to also be the default on phones. The ability for users to switch is also very powerful, and having a strong, usable, and supported alternative—that is, KDE/Plasma—for the Librem 5 offers the best of the “unified default” world and the “usable user choice” worlds.

Symbiotic GNOME and KDE partnerships

Purism has partnered with both GNOME and KDE for the Librem 5; what this means simply is that users running PureOS on their Librem 5 will get the choice of a GNOME environment or a KDE/Plasma environment, and the user could always switch between the two, like what is already the case on computers running PureOS. Will there be other partnerships in the future? We imagine so, since we will be happy to support any and all ethical OSes, GNU distributions, and want to make sure that the future is bright for a non-Android-non-iOS world.

While the initial GNOME and KDE partnerships mean uplifting diversity at the top level (and greater choice for users), each have a slightly different developmental and support roadmap. The reason for this is pragmatic, since KDE is very far along with their “Plasma” mobile desktop environment, while GNOME is farther behind currently. Investing time and efforts to advance the status of mobile GNOME/GTK+, aligns with our longer-term goals of a unified default desktop environment for PureOS, offering a convenient default for users. Diversity is why we are supporting and developing both GNOME/GTK+ and KDE/Plasma.

Therefore:

  • KDE: Purism is investing in hardware design, development kits, and supporting the KDE/Plasma community, and will be sharing all early documentation, hardware designs, and kernel development progress with the core KDE/Plasma developers and community.
  • GNOME: Purism is investing the same in hardware design, development kits, and supporting the GNOME/GTK+ community as we are with the KDE/Plasma community. In addition, Purism is needing to lead some of the development within the GNOME community, since there is not a large community around an upstream-first GNOME/GTK+ for mobile yet.

Choice is good, redundancy is good, but those are ideal when there is minimal additional investment required to accomplish technological parity. Since Purism uses GNOME as the default desktop environment within PureOS on our laptops, we figured we are going to invest some direct development efforts in GNOME/GTK+ for mobile to stay consistent across our default platforms. Adding KDE as a second desktop environment is directly aligned with our beliefs, and we are very excited to support KDE/Plasma on our Librem 5 phone as well as within PureOS for all our hardware. We will support additional efforts, if they align with our strict beliefs.

Why not just use KDE/Plasma and call it a day?

If we were doing short-term planning it would be easy to “just use Plasma” for the Librem 5, but that would undermine our long-term vision of having a consistent look/feel across all our devices, where GNOME/GTK+ is already the default and what we’ve invested in. Supporting both communities, while advancing GNOME/GTK+ on mobile to allow it to catch up, aligns perfectly with our short-term goals (offering Plasma on our Librem 5 hardware for early adopters who prefer this option), while meeting our long-term vision (offering a unified GNOME stack as our primary technological stack across all our hardware). It is also a good way to give back to a project that needs our help.

Why not just push GNOME and GTK+ and forward?

Because having an amazingly built Plasma offering available early to test and ship to users is a superb plan in many ways—not just for redundancy, but also because KDE/Plasma also aligns so well with our beliefs. The product readiness across these two desktop environments are so different it is not easy to compare side-by-side.

Empowering both communities is possible

Overall, Purism is investing the same amount across hardware, boot loader, kernel, drivers and UI/UX. These are shared resources. The deviation boils down to:

  • GTK+ and the GNOME “shell” development, that Purism is planning to be directly invested in, in close collaboration with upstream
  • Community support: by being involved in both communities, we are effectively doubling our efforts on supporting those communities, but that is a small cost for the greater benefit of users.

Supporting both KDE/Plasma and GNOME means we will continue to build, support, and release software that works well for users across Purism hardware and within PureOS. Purism fully acknowledges that each platform is in different release states, and will be working with each community in the areas required—be that software development, hardware development kits donated, community outreach, conference sponsorship, speaking engagements, and offering product for key personnel.


Update/P.S.: for the GNOME side of things, we are in close collaboration with upstream GNOME, and have followed GNOME Shell maintainers’ recommendations to have a simpler, Wayland-only shell (“phosh”) developed. You can learn more about it in our 2018 March 3rd technical report, in the “Compositor and Shell” section. So rest assured, those decisions have been taken with the “blessing” of upstream, based on purely technical grounds.

Librem 5 Phone Progress Report – The First of Many More to Come!

First, let me apologize for the silence. It was not because we went into hibernation for the winter, but because we were so busy in the initial preparation and planning of a totally new product while simultaneously orienting an entirely new development team. Since we are more settled into place now, we want to change this pattern of silence and provide regular updates. Purism will be giving weekly news update posts regarding the Librem 5 phone project, alternating progress reports on two fronts:

  • from the technology development point of view (the hardware, kernel, OS, etc.);
  • from the design department (UI+UX), and our collaboration with GNOME and KDE.

To kickoff this new update process, today’s post will discuss the organizational and technological progress of the Librem 5 project since November 2017.

New Team

Just after our successful pre-order crowdfunding campaign (by the way, thank you to all of the backers!) we started to reach out to people who had applied for jobs related to the Librem 5 project. We had well over 100 applicants who showed great passion for the project and had excellent resumes.

Our applicants came from all over the world  with some of the most diverse backgrounds I have ever seen. Todd Weaver (CEO) and myself did more than 80 interviews with applicants over a two weeks period. In the end, we had to narrow down to 15 people that we would make offers to; it was with great regret that we had to turn down so many stellar applicants, but we had to make decisions in a timely fashion and unfortunately the budget isn’t unlimited. During the weeks that followed, we negotiated terms with our proposed team members and started to roll new people into the team (with all that involves in an organizational setting). All of the new team members are now on board as of January 2018. They are not yet shown on our team page, but we will add them soon and make an announcement to present all the individuals who have recently joined our team.

As amazing as our community is, we also received applications from individuals who are so enthusiastic about our project that they want to help us as volunteers! We will reach out to them shortly, now that the core team is in place and settled.

There are so many people to thank for the successful jump start of our phone development project! It was amazing for us to see how much energy and interest we were able to spark with our project. We want to give a big thank you to everyone for reaching out to us and we really appreciate every idea and applicant.

CPU / System On Chip

Block Diagram i.MX6

During our early phase we used a NXP i.MX6 SOC (System On Chip) to begin software evaluation, and the results were pretty promising. This was why we listed the i.MX6 in the campaign description. The most important feature of the i.MX6 was that it is one of only a handful of SOCs supported by a highly functional free software GPU driver set, the Etnaviv driver. The Etnaviv driver has been included in the Linux mainline kernel for quite some time and the matching MESA support has evolved nicely. Briefly after our announcement we were contacted by one of the key driving forces behind the Etnaviv development effort which provides us with valuable insight in to this complex topic.

 

Block Diagram i.MX8

Further work with the i.MX6 showed us that it still uses quite a lot of power so when put under load it would drain a battery quickly, as well as warm up the device.

NXP had been talking about a new family of SOCs, the i.MX8, which would feature a new silicon processor and updated architecture. The release of the i.MX8 had been continuously postponed. Nevertheless, once we realized that the i.MX6 might be too power hungry, the i.MX8 became appealing to us. Hardware prototype operations are always tricky because you have to plan for emerging technologies that you meld with existing parts or materials. Components from original manufacturers sometimes never get released, are discontinued or the availability from the factory grinds to a halt for reasons beyond our control. This is the function of engaging in prototype development so that we can suffer the slings and arrows for you to provide the customer the best possible end product. We have been in active communication with all of our suppliers preparing a development plan that is beneficial for all of us.

At CES in Las Vegas, NXP announced the product release dates for their new SOC, the i.MX8M, along with a set of documentation. This is currently the most likely candidate we will use in the Librem 5. We are very excited about this timely announcement! At Embedded World in Nürnberg, Germany, NXP will announce details and a roadmap. We will be attending and discuss with NXP directly about the i.MX8M for the Librem 5.

We have also decided to use AARCH64, a.k.a. “ARM64”, for the phone software builds as soon as we have i.MX8 hardware. A build server for building ARM64 is now in place and the PureOS development team is beginning to work with the Librem 5 development team on the build process. Adding a second architecture for the FSF endorsed PureOS—that will run on Librem laptops as well as the Librem 5 phone—is a major undertaking that will benefit all future Librem 5 phone development.

Prototype Display for Development Boards

Since the i.MX8 is still not yet easily available, and in order not to unnecessarily slow development progress, we need similar hardware to start developing software. We switched to an i.MX6 Quad Plus board which should provide similar speed for the GPU to what we will find in the i.MX8M. From our contact from the Etnaviv developers we know that they are heavily working on the i.MX8M support so we can expect that Etnaviv will be working on it within the year.

One of the big tasks of our software and design teams, working with our partners (GNOME, KDE, Matrix, Nextcloud, and Monero), will be to create a proper User Interface (UI) and User Experience (UX) for a phone screen. The challenges are that the screen will be between 5″ to 5.5″ diagonally with a resolution of up to full HD (1920×1080), and a functional touchscreen! The amazing teams developing GNOME and KDE/Plasma have already done a great job laying the groundwork technologies and setting up this kind of interface to build, develop, and test with. With such great partners and development teams we are confident that we can successfully integrate the freedom, privacy, and security of PureOS with phone hardware to provide a beautiful user experience.

To help with development, we are already in the process of sourcing components to attach 5.5″ full HD displays to our development boards. Our development boards are already booting a mainline kernel into a Wayland UI nicely. We are evaluating similar displays from several manufacturers. We found a supplier for a matching adapter logic board (HDMI to MIPI). Our hardware engineer has already designed an additional adapter for interfacing the display’s touchscreen so that we will realistically have a 5.5″ full HD screen with touch capability on our development boards.

Potential Manufacturing Sites

The overall plan is to have a custom device manufacturing process setup somewhere where we can manufacture our own devices. Since November of last year we have been intensively researching and evaluating potential manufacturing partners. So far we have been in contact with over 80 potential fabricators and are in the process of negotiating capabilities and terms. No decision has been made yet. We have some promising prospects from all over the world, including Asia, Europe and the USA, and we plan on visiting some of these sites in person possibly by the end of February or March.

Cooperative Relationships

Now that the development team is in place we will be reaching out to our partners. Our UI/UX design team along with phone dev team are working with the GNOME UI/UX team to develop a path forward for mobile interfaces. We will also reach out to others who have partnered with us during the campaign, such as the KDE/Plasma team, Matrix, Nextcloud, Monero and many more.

Conclusion

I hope that the fog has been lifted, and we have answered questions you might have or assuaged fears of our silence. We hope that you enjoyed this first dive into our development process. We here at Purism are all very excited about the Librem 5 phone project, as we are passionate about all of our products, with the phone holding a special place in our hearts and those of the Free Software community. That’s what makes us different from companies rolling out “yet another Android phone”, swapping color palettes or removing headphone jacks under the guise of “innovation”…

See you next week for more news on the Librem 5 project!

Purism Attends Chaos Communication Congress

Chaos Computer Club hosts the CCC

We are attending the Chaos Communication Congress between December 27th – 30th in Leipzig, Germany. This is one of the largest gatherings of people who are interested in computer security, cryptography, privacy, and free speech in the world.

Two of our staff will be attending the event. Youness Alaoui and Zlatan Todoric hope to connect with those going or who are interested in learning more about the Congress. Please contact them on #Purism IRC channel on Freenode. Zlatan’s handle is zlatan, and Youness’ handle is KaKaRoTo.

They can’t wait to meet you at the Chaos Communication Congress!

FSF adds PureOS to list of endorsed GNU/Linux distributions

BOSTON, Massachusetts, USA — Thursday, December 21, 2017 — The Free Software Foundation (FSF) today announced the addition of PureOS to its list of recommended GNU/Linux distributions.

The FSF’s list showcases GNU/Linux operating system distributions whose developers have made a commitment to follow its Guidelines for Free System Distributions. Each one includes and endorses exclusively free “as in freedom” software.

After extensive evaluation and many iterations, the FSF concluded that PureOS, a modern and user-friendly Debian-derived distribution, meets these criteria.

“The FSF’s high standards for distributions help users know which ones will honor their desire to be fully in control of their computers and devices. These standards also help drive the development work needed to make the free world’s tools more practical and powerful than the proprietary dystopia exemplified by Windows, iOS, and Chrome. PureOS is living—and growing—proof that you can meet ethical standards while also achieving excellence in user experience,” said John Sullivan, FSF’s executive director.

“PureOS is a GNU operating system that embodies privacy, security, and convenience strictly with free software throughout. Working with the Free Software Foundation in this multi-year endorsement effort solidifies our longstanding belief that free software is the nucleus for all things ethical for users. Using PureOS ensures you are using an ethical operating system, committed to providing the best in privacy, security, and freedom,” said Todd Weaver, Founder & CEO of Purism.

FSF’s licensing and compliance manager, Donald Robertson, added,

“An operating system like PureOS is a giant collection of software, much of which in the course of use encourages installation of even more software like plugins and extensions. Issues are inevitable, but the team behind PureOS worked incredibly hard to fix everything we identified. They didn’t just fix the issues for their own distribution—they sent fixes upstream, and are developing new extension ‘store’ mechanisms that won’t recommend nonfree software to users. Our endorsement means we are confident not just in the current state of affairs, but also in the team’s commitment to quickly address any problems that do arise.”

PureOS is developed through a combination of volunteer contributions and work funded by the company Purism. The FSF’s announcement today is about the PureOS distribution, which can be installed by users on many kinds of computers and devices. It is not a certification of any particular hardware shipping with PureOS. Any such endorsements will be announced separately as part of the FSF’s Respects Your Freedom device certification program.

About the FSF

The Free Software Foundation, founded in 1985, is dedicated to promoting computer users’ right to use, study, copy, modify, and redistribute computer programs. The FSF promotes the development and use of free (as in freedom) software—particularly the GNU operating system and its GNU/Linux variants—and free documentation for free software. The FSF also helps to spread awareness of the ethical and political issues of freedom in the use of software, and its Web sites, located at fsf.org and gnu.org, are an important source of information about GNU/Linux. Donations to support the FSF’s work can be made at donate.fsf.org. Its headquarters are in Boston, MA, USA. More information about the FSF, as well as important information for journalists and publishers, is at fsf.org/press.

About the GNU Operating System and Linux

Richard Stallman announced in September 1983 the plan to develop a free software Unix-like operating system called GNU. GNU is the only operating system developed specifically for the sake of users’ freedom. See gnu.org/gnu/the-gnu-project.html.

In 1992, the essential components of GNU were complete, except for one, the kernel. When in 1992 the kernel Linux was re-released under the GNU GPL, making it free software, the combination of GNU and Linux formed a complete free operating system, which made it possible for the first time to run a PC without nonfree software. This combination is the GNU/Linux system. For more explanation, see the GNU FAQ entry about Linux.

About Purism

Purism is a Social Purpose Corporation devoted to bringing security, privacy, software freedom, and digital independence to everyone’s personal computing experience. With operations based in San Francisco (California) and around the world, Purism manufactures premium-quality laptops, tablets and phones, creating beautiful and powerful devices meant to protect users’ digital lives without requiring a compromise on ease of use. Purism designs and assembles its hardware in the United States, carefully selecting internationally sourced components to be privacy-respecting and fully Free-Software-compliant. Security and privacy-centric features come built-in with every product Purism makes, making security and privacy the simpler, logical choice for individuals and businesses.

Media Contact

Marie Williams, Coderella / Purism
+1 415-689-4029
pr@puri.sm
See also the Purism press room for additional tools and announcements.
 

Donald Robertson, III
Licensing & Compliance Manager, Free Software Foundation
+1 (617) 542 5942
licensing@fsf.org

We love Ethical Design


In our wish to bring our contribution to the betterment of society, wherever we plan to work on refining our products or existing software, we will conform to the Ethical Design Manifesto. Our philosophy and social purpose have always been in perfect unison with the principles stated in the Ethical Design Manifesto, and having it as part of our internal design team’s policy is a good way to make sure that we always keep it in mind.

What is Ethical Design?

The goal of “ethical” design is to develop technology that is respectful of human beings whoever they are. It encourages the adoption of ethical business models and, all together, it is favoring a more ethical society.

According to the manifesto, ethical design aims to respect:

  • Human Rights: “Technology that respects human rights is decentralised, peer-to-peer, zero-knowledge, end-to-end encrypted, free and open source, interoperable, accessible, and sustainable. It respects and protects your civil liberties, reduces inequality, and benefits democracy.”
  • Human Effort: “Technology that respects human effort is functional, convenient, and reliable. It is thoughtful and accommodating; not arrogant or demanding. It understands that you might be distracted or differently-abled. It respects the limited time you have on this planet.”
  • Human Experience: “Technology that respects human experience is beautiful, magical, and delightful. It just works. It’s intuitive. It’s invisible. It recedes into the background of your life. It gives you joy. It empowers you with superpowers. It puts a smile on your face and makes your life better.”

Growing the seed of an ethical society

Working towards an “ethical society” may sound like fighting windmills. I personally see it as a global, constant yet disorganized wish that nonetheless tends to materialize from time to time through a common concerted effort. I don’t think that this effort is about changing some thing because of its unethical nature; it has nothing to do with a fight. Instead, it is about growing the seed of a more ethical thing that would exist next to it.

In line with this goal and our social purpose is the fact that we aim to work in an “upstream first” way as part of the Free Software community; in order to contribute to the common effort toward growing this ethical seed, any software development and improvement on top of an existing project is intended to be discussed and co-developed upstream first. We don’t want to reinvent the wheel and fork existing projects just because we don’t like the colors of the paint on the wall! This would only fraction the community’s resources and add confusion for users.

There are so many amazing free software projects that share our philosophy, and we hope to contribute while also ensuring these pieces of software respect human rights, human effort and human experience. These are my guiding principles for Purism’s UI and UX design projects.

A Primer Guide to Reverse Engineering

Over the years, many people asked me to teach them what I do, or to explain to them how to reverse engineer assembly code in general. Sometimes I hear the infamous “How hard can it be?” catchphrase. Last week someone I was discussing with thought that the assembly language is just like a regular programming language, but in binary form—it’s easy to make that mistake if you’ve never seen what assembly is or looks like. Historically, I’ve always said that reverse engineering and ASM is “too complicated to explain” or that “If you need help to get started, then you won’t be able to finish it on your own” and various other vague responses—I often wanted to explain to others why I said things like that but I never found a way to do it. You see, when something is complex, it’s easy to say that it’s complex, but it’s much harder to explain to people why it’s complex.

I was lucky to recently stumble onto a little function while reverse engineering a function that was both simple and complex, where figuring out what it does was an interesting challenge that I can easily walk you through. This function wasn’t a difficult thing to understand, and by far, it’s not one of the hard or complex things to reverse engineer, but this one is “small and complex enough” that it’s a perfect example to explain, without writing an entire book or getting into the more complex aspects of reverse engineering. So today’s post serves as a “primer” guide to reverse engineering for all of those interested in the subject. It is a required read in order to understand the next blog posts I would be writing about reverse engineering.

Note: some function and component names in this blog post have been scrambled, with names such as “BOB”, “ALICE” and “QUEEN”.

Ready? Strap on your geek helmet and let’s get started!


DISCLAIMER: I might make false statements in the blog post below, some by mistake, some intentionally for the purpose of vulgarizing the explanations. For example, when I say below that there are 9 registers in X86, I know there are more (SSE, FPU, or even just the DS or EFLAGS registers, or purposefully not mentioning EAX instead of RAX, etc.), but I just don’t want to complicate matters by going too wide in my explanations.


A prelude

First things first, you need to understand some basic concepts, such as “what is ASM exactly”. I will explain some basic concepts but not all the basic concepts you might need. I will assume that you know at least what a programming language is and know how to write a simple “hello world” in at least one language, otherwise you’ll be completely lost.

So, ASM is the Assembly language, but it’s not the actual binary code that executes on the machine. It is however, very similar to it. To be more exact, the assembly language is a textual representation of the binary instructions given to the microprocessor. You see, when you compile your regular C program into an executable, the compiler will transform all your code into some very, very, very basic instructions. Those instructions are what the CPU will understand and execute. By combining a lot of small, simple and specific instructions, you can do more complex things. That’s the basis of any programming language, of course, but with assembly, the building blocks that you get are very limited. Before I’ll talk about instructions, I want to explain two concepts first which you’ll need to follow the rest of the story.

The stack

First I’ll explain what “the stack” is. You may have heard of it before, or maybe you didn’t, but the important thing to know is that when you write code, you have two types of memory:

  • The first one is your “dynamic memory”, that’s when you call ‘malloc’ or ‘new’ to allocate new memory, this goes from your RAM upward (or left-to-right), in the sense that if you allocate 10 bytes, you’ll first get address 0x1000 for example, then when you allocate another 30 bytes, you’ll get address 0x100A, then if you allocate another 16 bytes, you’ll get 0x1028, etc.
  • The second type of memory that you have access to is the stack, which is different, instead it grows downward (or right-to-left), and it’s used to store local variables in a function. So if you start with the stack at address 0x8000, then when you enter a function with 16 bytes worth of local variables, your stack now points to address 0x7FF0, then you enter another function with 64 bytes worth of local variables, and your stack now points to address 0x7FB0, etc. The way the stack works is by “stacking” data into it, you “push” data in the stack, which puts the variable/data into the stack and moves the stack pointer down, you can’t remove an item from anywhere in the stack, you can always only remove (pop) the last item you added (pushed). A stack is actually an abstract type of data, like a list, an array, a dictionary, etc. You can read more about what a stack is on wikipedia and it shows you how you can add and remove items on a stack with this image:

The image shows you what we call a LIFO (Last-In-First-Out) and that’s what a stack is. In the case of the computer’s stack, it grows downward in the RAM (as opposed to upward in the above image) and is used to store local variables as well as the return address for your function (the instruction that comes after the call to your function in the parent function). So when you look at a stack, you will see multiple “frames”, you’ll see your current function’s stack with all its variables, then the return address of the function that called it, and above it, you’ll see the previous function’s frame with its own variables and the address of the function that called it, and above, etc. all the way to the main function which resides at the top of the stack.

Here is another image that exemplifies this:

The registers

The second thing I want you to understand is that the processor has multiple “registers”. You can think of a register as a variable, but there are only 9 total registers on x86, with only 7 of them usable. So, on the x86 processor, the various registers are: EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP, EIP.

There are two registers in there that are special:

  • The EIP (Instruction Pointer) contains the address of the current instruction being executed.
  • The ESP (Stack Pointer) contains the address of the stack.

Access to the registers is extremely fast when compared to accessing the data in the RAM (the stack also resides on the RAM, but towards the end of it) and most operations (instructions) have to happen on registers. You’ll understand more when you read below about instructions, but basically, you can’t use an instruction to say “add value A to value B and store it into address C”, you’d need to say “move value A into register EAX, then move value B into register EBX, then add register EAX to register EBX and store the result in register ECX, then store the value of register ECX into the address C”.

The instructions

Let’s go back to explaining instructions now. As I explained before, the instructions are the basic building blocks of the programs, and they are very simple, they take the form of:

INS OP1, OP2, OP3

Where “INS” is the instruction”, and OP1, OP2, OP3 is what we call the “operand”, most instructions will only take 2 operands, some will take no operands, some will take one operand and others will take 3 operands. The operands are usually registers. Sometimes, the operand can be an actual value (what we call an “immediate value”) like “1”, “2” or “3”, etc. and sometimes, the operand is a relative position from a register, like for example “[%eax + 4]” meaning the address pointed to by the %eax register + 4 bytes. We’ll see more of that shortly. For now, let’s give you the list of the most common and used instructions:

  • MOV“: move data from one operand into another
  • ADD/SUB/MUL/DIV“: Add, Substract, Multiply, Divide one operand with another and store the result in a register
  • AND/OR/XOR/NOT/NEG“: Perform logical and/or/xor/not/negate operations on the operand
  • SHL/SHR“: Shift Left/Shift Right the bits in the operand
  • CMP/TEST“: Compare one register with an operand
  • JMP/JZ/JNZ/JB/JS/etc.”: Jump to another instruction (Jump unconditionally, Jump if Zero, Jump if Not Zero, Jump if Below, Jump if Sign, etc.)
  • PUSH/POP“: Push an operand into the stack, or pop a value from the stack into a register
  • CALL“: Call a function. This is the equivalent of doing a “PUSH %EIP+4” + “JMP”. I’ll get into calling conventions later..
  • RET“: Return from a function. This is the equivalent of doing a “POP %EIP”

That’s about it, that’s what most programs are doing. Of course, there’s a lot more instructions, you can see a full list here, but you’ll see that most of the other instructions are very obscure or very specific or variations on the above instructions, so really, this represents most of the instructions you’ll ever encounter.

I want to explain one thing before we go further down: there is an additional register I didn’t mention before called the FLAGS register, which is basically just a status register that contains “flags” that indicate when some arithmetic condition happened on the last arithmetic operation. For example, if you add 1 to 0xFFFFFFFF, it will give you ‘0’ but the “Overflow flag” will be set in the FLAGS register. If you substract 5 from 0, it will give you 0xFFFFFFFB and the “Sign flag” will be set because the result is negative, and if you substract 3 from 3, the result will be zero and the “Zero flag” will be set.

I’ve shown you the “CMP” instruction which is used to compare a register with an operand, but you might be wondering, “What does it mean exactly to ‘compare’?” Well, it’s simple, the CMP instruction is the same thing as the SUB instruction, in that, it substracts one operand from another, but the difference is that it doesn’t store the result anywhere. However, it does get your flags updated in the FLAGS register. For example, if I wanted to compare %EAX register with the value ‘2’, and %EAX contains the value 3, this is what’s going to happen: you will substract 2 from the value, the result will be 1, but you don’t care about that, what you care about is that the ZF (Zero flag) is not set, and the SF (Sign flag is not set), which means that %eax and ‘2’ are not equal (otherwise, ZF would be set), and that the value in %eax is superior to 2 (because SF is not set), so you know that “%eax > 2” and that’s what the CMP does.

The TEST instruction is very similar but it does a logical AND on the two operands for testing, so it’s used for comparing logical values instead of arithmetic values (“TEST %eax, 1” can be used to check if %eax contains an odd or even number for example).

This is useful because the next bunch of instructions I explained in the list above is conditional Jump instructions, like “JZ” (jump if zero) or “JB” (jump if below), or “JS” (jump if sign), etc. This is what is used to implement “if, for, while, switch/case, etc.” it’s as simple as doing a “CMP” followed by a “JZ” or “JNZ” or “JB”, “JA”, “JS”, etc.

And if you’re wondering what’s the difference between a “Jump if below” and “Jump if sign” and “Jump if lower”, since they all mean that the comparison gave a negative result, right? Well, the “jump if below” is used for unsigned integers, while “jump if lower” is used for signed integers, while “jump if sign” can be misleading. An unsigned 3 – 4 would give us a very high positive result… something like that, in practice, JB checks the Carry Flag, while JS checks the Sign Flag and JL checks if the Sign Flag is equal to the Overflow flag. See the Conditional Jump page for more details.

A practical example

Here’s a very small and simple practical example, if you have a simple C program like this:

int main() {
   return add_a_and_b(2, 3);
}

int add_a_and_b(int a, int b) {
   return a + b;
}

It would compile into something like this:

_main:
   push   3                ; Push the second argument '3' into the stack
   push   2                ; Push the first argument '2' into the stack
   call   _add_a_and_b     ; Call the _add_a_and_b function. This will put the address of the next
                           ; instruction (add) into the stack, then it will jump into the _add_a_and_b
                           ; function by putting the address of the first instruction in the _add_a_and_b
                           ; label (push %ebx) into the EIP register
   add    %esp, 8          ; Add 8 to the esp, which effectively pops out the two values we just pushed into it
   ret                     ; Return to the parent function.... 

_add_a_and_b:
   push   %ebx             ; We're going to modify %ebx, so we need to push it to the stack
                           ; so we can restore its value when we're done
   mov    %eax, [%esp+8]   ; Move the first argument (8 bytes above the stack pointer) into EAX
   mov    %ebx, [%esp+12]  ; Move the second argument (12 bytes above the stack pointer) into EBX
   add    %eax, %ebx       ; Add EAX and EBX and store the result into EAX
   pop    %ebx             ; Pop EBX to restore its previous value
   ret                     ; Return back into the main. This will pop the value on the stack (which was
                           ; the address of the next instruction in the main function that was pushed into
                           ; the stack when the 'call' instruction was executed) into the EIP register

Yep, something as simple as that, can be quite complicated in assembly. Well, it’s not really that complicated actually, but a couple of things can be confusing.

You have only 7 usable registers, and one stack. Every function gets its arguments passed through the stack, and can return its return value through the %eax register. If every function modified every register, then your code will break, so every function has to ensure that the other registers are unmodified when it returns (other than %eax). You pass the arguments on the stack and your return value through %eax, so what should you do if need to use a register in your function? Easy: you keep a copy on the stack of any registers you’re going to modify so you can restore them at the end of your function. In the _add_a_and_b function, I did that for the %ebx register as you can see. For more complex function, it can get a lot more complicated than that, but let’s not get into that for now (for the curious: compilers will create what we call a “prologue” and an “epilogue” in each function. In the prologue, you store the registers you’re going to modify, set up the %ebp (base pointer) register to point to the base of the stack when your function was entered, which allows you to access things without keeping track of the pushes/pops you do throughout the function, then in the epilogue, you pop the registers back, restore %esp to the value that was saved in %ebp, before you return).

The second thing you might be wondering about is with these lines:

mov %eax, [%esp+8]
mov %ebx, [%esp+12]

And to explain it, I will simply show you this drawing of the stack’s contents when we call those two instructions above:

For the purposes of this exercise, we’re going to assume that the _main function is located in memory at the address 0xFFFF0000, and that each instructoin is 4 bytes long (the size of each instruction can vary depending on the instruction and on its operands). So you can see, we first pushed 3 into the stack, %esp was lowered, then we pushed 2 into the stack, %esp was lowered, then we did a ‘call _add_a_and_b’, which stored the address of the next instruction (4 instructions into the main, so ‘_main+16’) into the stack and esp was lowered, then we pushed %ebx, which I assumed here contained a value of 0, and the %esp was lowered again. If we now wanted to access the first argument to the function (2), we need to access %esp+8, which will let us skip the saved %ebx and the ‘Return address’ that are in the stack (since we’re working with 32 bits, each value is 4 bytes). And in order to access the second argument (3), we need to access %esp+12.

Binary or assembly?

One question that may (or may not) be popping into your mind now is “wait, isn’t this supposed to be the ‘computer language’, so why isn’t this binary?” Well, it is… in a way. As I explained earlier, “the assembly language is a textual representation of the binary instructions given to the microprocessor”, what it means is that those instructions are given to the processor as is, there is no transformation of the instructions or operands or anything like that. However, the instructions are given to the microprocessor in binary form, and the text you see above is just the textual representation of it.. kind of like how “68 65 6c 6c 6f” is the hexadecimal representation of the ASCII text “hello”. What this means is that each instruction in assembly language, which we call a ‘mnemonic’ represents a binary instruction, which we call an ‘opcode’, and you can see the opcodes and mnemonics in the list of x86 instructions I gave you above. Let’s take the CALL instruction for example. The opcode/mnemonic list is shown as:

Opcode Mnemonic Description
E8 cw CALL rel16 Call near, relative, displacement relative to next instruction
E8 cd CALL rel32 Call near, relative, displacement relative to next instruction
FF /2 CALL r/m16 Call near, absolute indirect, address given in r/m16
FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32
9A cd CALL ptr16:16 Call far, absolute, address given in operand
9A cp CALL ptr16:32 Call far, absolute, address given in operand
FF /3 CALL m16:16 Call far, absolute indirect, address given in m16:16
FF /3 CALL m16:32 Call far, absolute indirect, address given in m16:32

This means that this same “CALL” mnemonic can have multiple addresses to call. Actually, there are four different possitiblities, each having a 16 bits and a 32 bits variant. The first possibility is to call a function with a relative displacement (Call the function 100 bytes below this current position), or an absolute address given in a register (Call the function whose address is stored in %eax) or an absolute address given as a pointer (Call the function at address 0xFFFF0100), or an absolute address given as an offset to a segment (I won’t explain segments now). In our example above, the “call _add_a_and_b” was probably stored as a call relative to the current position with 12 bytes below the current instruction (4 bytes per instruction, and we have the CALL, ADD, RET instructions to skip). This means that the instruction in the binary file was encoded as “E8 00 00 00 0C” (The E8 opcode to mean a “CALL near, relative”, and the “00 00 00 0C” to mean 12 bytes relative to the current instruction). Now, the most observant of you have probably noticed that this CALL instruction takes 5 bytes total, not 4, but as I said above, we will assume it’s 4 bytes per instruction just for the sake of keeping things simple, but yes, the CALL (in this case) is 5 bytes, and other instructions will sometimes have more or less bytes as well.

I chose the CALL function above for example, because I think it’s the least complicated to explain.. other instructions have even more complicated opcodes and operands (See the ADD and ADC (Add with Cary) instructions for example, you’ll notice the same opcodes shared between them even, so they are the same instruction, but it’s easy to give them separate mnemonics to differentiate their behaviors).

Here’s a screenshot showing a side by side view of the Assembly of a function with the hexadecimal view of the binary:

As you can see, I have my cursor on address 0xFFF6E1D6 on the assembly view on the left, which is also highlighted on the hex view on the right. That address is a CALL instruction, and you can see the equivalent hex of “E8 B4 00 00 00”, which means it’s a CALL near, relative (E8 being the opcode for it) and the function is 0xB4 (180) bytes below our current position of 0xFFF6E1D6.

If you open the file with a hexadecimal editor, you’ll only see the hex view on the right, but you need to put the file into a Disassembler (such as the IDA disassembler which I’m using here, but there are cheaper alternatives as well, the list can be long), and the disassembler will interpret those binary opcodes to show you the textual assembly representation which is much much easier to read.

Some actual reverse engineering

Now that you have the basics, let’s do a quick reverse engineering exercise… This is a very simple function that I’ve reversed recently, it comes from the SiliconInit, and it’s used to validate the UPD configuration structure (used to tell it what to do).

Here is the Assembly code for that function:

This was disassembled using IDA 7.0 (The Interactive DisAssembler) which is an incredible (but expensive) piece of software. There are other disassemblers which can do similar jobs, but I prefer IDA personally. Let’s first explain what you see on the screen.

On the left side, you see “seg000:FFF40xxx” this means that we are in the segment “seg000” at the address 0xFFF40xxx. I won’t explain what a segment is, because you don’t need to know it. The validate_upd_config function starts at address 0xFFF40311 in the RAM, and there’s not much else to understand. You can see how the address increases from one instruction to the next, it can help you calculate the size in bytes that each instruction takes in RAM for example, if you’re curious of course… (the XOR is 2 bytes, the CMP is 2 bytes, etc.).

As you’ve seen in my previous example, anything after a semicolon (“;”) is considered a comment and can be ignored. The “CODE XREF” comments are added by IDA to tell us that this code has a cross-references (is being called by) some other code. So when you see “CODE XREF: validate_upd_config+9” (at 0xFF40363, the RETN instruction), it means this instruction is being called (referenced by) from the function validate_upd_config and the “+9” means 9 bytes into the function (so since the function starts at 0xFFF40311, it means it’s being called from the instruction at offset 0xFFF4031A. The little “up” arrow next to it means that it comes from above the current position in the code, and if you follow the grey lines on the left side of the screen, you can follow that call up to the address 0xFFF4031A which contains the instruction “jnz short locret_FFF40363”. I assume the “j” letter right after the up arrow is to tell us that the reference comes from a “jump” instruction.

As you can see in the left side of the screen, there are a lot of arrows, that means that there’s a lot of jumping around in the code, even though it’s not immediatly obvious. The awesome IDA software has a “layout view” which gives us a much nicer view of the code, and it looks like this:

Now you can see each block of code separately in their own little boxes, with arrows linking all of the boxes together whenever a jump happens. The green arrows mean that it’s a conditional jump when the condition is successful, while the red arrows means the condition was not successful. This means that a “JZ” will show a green arrow towards the code it would jump to if the result is indeed zero, and a red arrow towards the block where the result is not zero. A blue arrow means that it’s an unconditional jump.

I usually always do my reverse engineering using the layout view, I find it much easier to read/follow, but for the purpose of this exercise, I will use the regular linear view instead, so I think it will be easier for you to follow with that instead. The reason is mostly because the layout view doesn’t display the address of each instruction, and it’s easier to have you follow along if I can point out exactly which instruction I’m looking it by mentioning its address.

Now that you know how to read the assembly code, you understand the various instructions, I feel you should be ready to reverse engineering this very simple assembly code (even though it might seem complex at first). I just need to give you the following hints first:

  • Because I’ve already reversed engineering it, you get the beautiful name “validate_upd_config” for the function, but technically, it was simply called “sub_FFF40311”
  • I had already reverse engineered the function that called it so I know that this function is receiving its arguments in an unusual way. The arguments aren’t pushed to the stack, instead, the first argument is stored in %ecx, and the second argument is stored in %edx
  • The first argument (%ecx, remember?) is an enum to indicate what type of UPD structure to validate, let me help you out and say that type ‘3’ is “ALICE” (The configuration structure for the QueenM, the MemoryInit function), and that type ‘5’ is “BOB” (The configuration structure for the QueenS, the SiliconInit function).
  • Reverse engineering is really about reading one line at a time, in a sequential manner, keep track of which blocks you reversed and be patient. You can’t look at it and expect to understand the function by viewing the big picture.
  • It is very very useful in this case to have a dual monitor, so you can have one monitor for the assembly, and the other monitor for your C code editor. In my case, I actually recently bought an ultra-wide monitor and I split screen between my IDA window and my emacs window and it’s great. It’s hard otherwise to keep going back and forth between the assembly and the C code. That being said, I would suggest you do the same thing here and have a window on the side showing you the assembly image above (not the layout view) while you read the explanation on how to reverse engineer it below.

Got it? All done? No? Stop sweating and hyperventilating… I’ll explain exactly how to reverse engineer this function in the next paragraph, and you will see how simple it turns out to be!

Let’s get started!

The first thing I do is write the function in C. Since I know the name and its arguments already, I’ll do that:

void validate_upd_config (uint8_t action, void *config) {
}

Yeah, there’s not much to it yet, and I set it to return “void” because I don’t know if it returns anything else, and I gave the first argument “action” as a “uint8_t” because in the parent function it’s used a single byte register (I won’t explain for now how to differentiate 1-byte, 2-bytes, 4-bytes and 8-bytes registers). The second argument is a pointer, but I don’t know it’s a pointer to what kind of structure exactly, so I just set it as a void *.

The first instruction is a “xor eax, eax”. What does this do? It XORs the eax register with the eax register and stores the result in the eax register itself, which is the same thing as “mov eax, 0”, because 1 XOR 1= 0 and 0 XOR 0 = 0, so if every bit in the eax register is logically XORed with itself, it will give 0 for the result. If you’re asking yourself “Why did the compiler decide to do ‘xor eax, eax’ instead of ‘mov eax, 0’ ?” then the answer is simple: “Because it takes less CPU clock cycles to do a XOR, than to do a move”, which means it’s more optimized and it will run faster. Besides, the XOR takes 2 bytes as you can see above (the address of the instructions jumped from FFF40311 to FFF40313), while a “mov eax, 0” would have taken 5 bytes. So it also helps keep the code smaller.

Alright, so now we know that eax is equal to 0, let’s keep that in mind and move along (I like to keep track of things like that as comments in my C code). Next instruction does a “cmp ecx, 3”, so it’s comparing ecx, which we already know is our first argument (uint8_t action), ok, it’s a comparison, not much to do here, again let’s keep that in mind and continue… the next instruction does a “jnz short loc_FFF40344”, which is more interesting, so if the previous comparison is NOT ZERO, then jump to the label loc_FFF40344 (for now ignore the “short”, it just helps us differentiate between the various mnemonics, and it means that the jump is a relative offset that fits in a “short word” which means 2 bytes, and you can confirm that the jnz instruction does indeed take only 2 bytes of code). Great, so there’s a jump if the result is NOT ZERO, which means that if the result is zero, the code will just continue, which means if the ecx register (action variable) is EQUAL (substraction is zero) to 3, the code will continue down to the next instruction instead of jumping… let’s do that, and in the meantime we’ll update our C code:

void validate_upd_config (uint8_t action, void *config) {
   // eax = 0
   if (action == 3) {
      // 0xFFF40318 
   } else {
      // loc_FFF40344
   }
}

The next instruction is “test edx, edx”. We know that the edx register is our second argument which is the pointer to the configuration structure. As I explained above, the “test” is just like a comparison, but it does an AND instead of a substraction, so basically, you AND edx with itself.. well, of course, that has no consequence, 1 AND 1 = 1, and 0 AND 0 = 0, so why is it useful to test a register against itself? Simply because the TEST will update our FLAGS register… so when the next instruction is “JZ” it basically means “Jump if the edx register was zero”… And yes, doing a “TEST edx, edx” is more optimized than doing a “CMP edx, 0”, you’re starting to catch on, yeay!

And indeed, the next instruction is “jz locret_FFF40363”, so if the edx register is ZERO, then jump to locret_FFF40363, and if we look at that locret_FFF40363, it’s a very simple “retn” instruction. So our code becomes:

void validate_upd_config (uint8_t action, void *config) {
  // eax = 0
  if (action == 3) {
    if (config == NULL)
       return; 
  } else {
    // loc_FFF40344
  }
}

Next! Now it gets slightly more complicated… the instruction is: “cmp dword ptr [edx], 554C424Bh”, which means we do a comparison of a dword (4 bytes), of the data pointed to by the pointer edx, with no offset (“[edx]” is the same as saying “edx[0]” if it was a C array for example), and we compare it to the value 554C424Bh… the “h” at the end means it’s a hexadecimal value, and with experience you can quickly notice that the hexadecimal value is all within the ASCII range, so using a Hex to ASCII converter, we realize that those 4 bytes represent the ASCII letters “KBLU” (which is why I manually added them as a comment to that instruction, so I won’t forget). So basically the instruction compares the first 4 bytes of the structure (the content pointed to by the edx pointer) to the string “KBLU”. The next instruction does a “jnz loc_FFF4035E” which means that if the comparison result is NOT ZERO (so, if they are not equal) we jump to loc_FFF4035E.

Instead of continuing sequentially, I will see what that loc_FFF4035E contains (of course, I did the same thing in all the previous jumps, and had to decide if I wanted to continue reverse engineering the jump or the next instruction, in this case, it seems better for me to jump, you’ll see why soon). The loc_FFF4035E label contains the following instruction: “mov, eax, 80000002h”, which means it stores the value 0x80000002 into the eax register, and then it jumps to (not really, it just naturally flows to the next instruction which happens to be the label) locret_FFF40363, which is just a “retn”. This makes our code into this:

uint32_t validate_upd_config (uint8_t action, void *config) {
  // eax = 0
  if (action == 3) {
    if (config == NULL)
       return 0; 
    if (((uint32_t *)config)[0] != 0x554C524B)
       return 0x80000002;
  } else {
    // loc_FFF40344
  }
}

The observant here will notice that I’ve changed the function prototype to return a uint32_t instead of “void” and my previous “return” has become “return 0” and the new code has a “return 0x80000002”. That’s because I realized at this point that the “eax” register is used to return a uint32_t value. And since the first instruction was “xor eax, eax”, and we kept in the back of our mind that “eax is initialized to 0”, it means that the use case with the (config == NULL) will return 0. That’s why I made all these changes…

Very well, let’s go back to where we were, since we’ve exhausted this jump, we’ll jump back in reverse to go back to the address FFF40322 and continue from there to the next instruction. It’s a “cmp dword ptr [edx+4], 4D5F4450h”, which compares the dword at edx+4 to 0x4D5F4450, which I know to be the ASCII for “PD_M”; this means that the last 3 instructions are used to compare the first 8 bytes of our pointer to “KBLUPD_M”… ohhh, light bulb above our heads, it’s comparing the pointer to the Signature of the ALICE structure (don’t forget, you weren’t supposed to know that the function is called validate_upd_config, or that the argument is a config pointer… just that it’s a pointer)! OK, now it makes sense, and while we’re at it—and since we are, of course, reading the QUEEN integration guide PDF, we then also realize what the 0x80000002 actually means. At this point, our code now becomes:

EFI_STATUS validate_upd_config (uint8_t action, void *config) {
  if (action == 3) {
    ALICE *upd = (ALICE *) config;
    if (upd == NULL)
       return EFI_SUCCESS; 
    if (upd->QueenUpdHeader.Signature != 0x4D5F4450554C524B /* 'KBLUPD_M'*/)
       return EFI_INVALID_PARAMETERS;
  } else {
    // loc_FFF40344
  }
}

Yay, this is starting to look like something… Now you probably got the hang of it, so let’s do things a little faster now.

  • The next line “cmp [edx+28h], eax” compares edx+0x28 to eax. Thankfully, we know now that edx points to the ALICE structure, and we can calculate that at offset 0x28 inside that structure, it’s the field StackBase within the QueenmArchUpd field…
  • and also, we still have in the back of our minds that ‘eax’ is initialized to zero, so, we know that the next 2 instructions are just checking if upd->QueenmArchUpd.StackBase is == NULL.
  • Then we compare the StackSize with 0x26000, but the comparison is using “jb” for the jump, which is “jump if below”, so it checks if StackSize < 0x26000,
  • finally it does a “test” with “edx+30h” (which is the BootloaderTolumSize field) and 0xFFF, then it does an unconditional jump to loc_FFF4035C, which itself does a “jz” to the return..
  • which means if (BootloaderTolumSize & 0xFFF == 0) it will return whatever EAX contained (which is zero),
  • but if it doesn’t, then it will continue to the next instruction which is the “mov eax, 80000002h”.

So, we end up with this code:

EFI_STATUS validate_upd_config (uint8_t action, void *config) {
  // eax = 0
  if (action == 3) {
    ALICE *upd = (ALICE *) config;
    if (upd == NULL)
       return 0;
    if (upd->QueenUpdHeader.Signature != 0x4D5F4450554C524B /* 'KBLUPD_M'*/)
       return EFI_INVALID_PARAMETERS;
    if (upd->QueenmArchUpd.StackBase == NULL)
        return EFI_INVALID_PARAMETERS;
    if (upd->QueenmArchUpd.StackSize < 0x2600)
        return EFI_INVALID_PARAMETERS;
    if (upd->QueenmArchUpd.BootloaderTolumSize & 0xFFF)
        return EFI_INVALID_PARAMETERS;
  } else {
    // loc_FFF40344
  }
  return EFI_SUCCESS
}

Great, we just solved half of our code! Don’t forget, we jumped one way instead of another at the start of the function, now we need to go back up and explore the second branch of the code (at offset 0xFFF40344). The code is very similar, but it checks for “KBLUPD_S” Signature, and nothing else. Now we can also remove any comment/notes we have (such as the note that eax is initialized to 0) and clean up, and simplify the code if there is a need.

So our function ends up being (this is the final version of the function):

EFI_STATUS validate_upd_config (uint8_t action, void *config) {
  if (action == 3) {
    ALICE *upd = (ALICE *) config;
    if (upd == NULL)
       return EFI_SUCCESS;
    if (upd->QueenUpdHeader.Signature != 0x4D5F4450554C524B /* 'KBLUPD_M'*/)
       return EFI_INVALID_PARAMETERS;
    if (upd->QueenmArchUpd.StackBase == NULL)
        return EFI_INVALID_PARAMETERS;
    if (upd->QueenmArchUpd.StackSize < 0x2600)
        return EFI_INVALID_PARAMETERS;
    if (upd->QueenmArchUpd.BootloaderTolumSize & 0xFFF)
        return EFI_INVALID_PARAMETERS;
  } else {
    BOB *upd = (BOB *) config;
    if (upd == NULL)
        return EFI_SUCCESS;
    if (upd->QueenUpdHeader.Signature != 0x535F4450554C524B /* 'KBLUPD_S'*/)
        return EFI_INVALID_PARAMETERS;
  }
  return EFI_SUCCESS
}

Now this wasn’t so bad, was it? I mean, it’s time consuming, sure, it can be a little disorienting if you’re not used to it, and you have to keep track of which branches (which blocks in the layout view) you’ve already gone through, etc. but the function turned out to be quite small and simple. After all, it was mostly only doing CMP/TEST and JZ/JNZ.

That’s pretty much all I do when I do my reverse engineering, I go line by line, I understand what it does, I try to figure out how it fits into the bigger picture, I write equivalent C code to keep track of what I’m doing and to be able to understand what happens, so that I can later figure out what the function does exactly… Now try to imagine doing that for hundreds of functions, some of them that look like this (random function taken from the QueenM module):

You can see on the right, the graph overview which shows the entirety of the function layout diagram. The part on the left (the assembly) is represented by the dotted square on the graph overview (near the middle). You will notice some arrows that are thicker than the others, that’s used in IDA to represent loops. On the left side, you can notice one such thick green line coming from the bottom and the arrow pointing to a block inside our view. This means that there’s a jump condition below that can jump back to a block that is above the current block and this is basically how you do a for/while loop with assembly, it’s just a normal jump that points backwards instead of forwards.

Finally, the challenge!

At the beginning of this post, I mentioned a challenging function to reverse engineer. It’s not extremely challenging—it’s complex enough that you can understand the kind of things I have to deal with sometimes, but it’s simple enough that anyone who was able to follow up until now should be able to understand it (and maybe even be able to reverse engineer it on their own).

So, without further ado, here’s this very simple function:

Since I’m a very nice person, I renamed the function so you won’t know what it does, and I removed my comments so it’s as virgin as it was when I first saw it. Try to reverse engineer it. Take your time, I’ll wait:

Alright, so, the first instruction is a “call $+5”, what does that even mean?

  1. When I looked at the hex dump, the instruction was simply “E8 00 00 00 00” which according to our previous CALL opcode table means “Call near, relative, displacement relative to next instruction”, so it wants to call the instruction 0 bytes from the next instruction. Since the call opcode itself is taking 5 bytes, that means it’s doing a call to its own function but skipping the call itself, so it’s basically jumping to the “pop eax”, right? Yes… but it’s not actually jumping to it, it’s “calling it”, which means that it just pushed into the stack the return address of the function… which means that our stack contains the address 0xFFF40244 and our next instruction to be executed is the one at the address 0xFFF40244. That’s because, if you remember, when we do a “ret”, it will pop the return address from the stack into the EIP (instruction pointer) register, that’s how it knows where to go back when the function finishes.
  2. So, then the instruction does a “pop eax” which will pop that return address into EAX, thus removing it from the stack and making the call above into a regular jump (since there is no return address in the stack anymore).
  3. Then it does a “sub eax, 0FFF40244h”, which means it’s substracting 0xFFF40244 from eax (which should contain 0xFFF40244), so eax now contains the value “0”, right? You bet!
  4. Then it adds to eax, the value “0xFFF4023F”, which is the address of our function itself. So, eax now contains the value 0xFFF4023F.
  5. It will then substract from EAX, the value pointed to by [eax-15], which means the dword (4 bytes) value at the offset 0xFFF4023F – 0xF, so the value at 0xFFF40230, right… that value is 0x1AB (yep, I know, you didn’t have this information)… so, 0xFFF4023F – 0x1AB = 0xFFF40094!
  6. And then the function returns.. with the value 0xFFF40094 in EAX, so it returns 0xFFF40094, which happens to be the pointer to the QUEEN_INFO_HEADER structure in the binary.

So, the function just returns 0xFFF40094, but why did it do it in such a convoluted way? The reason is simple: because the QUEEN-S code is technically meant to be loaded in RAM at the address 0xFFF40000, but it can actually reside anywhere in the RAM when it gets executed. Coreboot for example doesn’t load it in the right memory address when it executes it, so instead of returning the wrong address for the structure and crashing (remember, most of the jumps and calls use relative addresses, so the code should work regardless of where you put it in memory, but in this case returning the wrong address for a structure in memory wouldn’t work), the code tries to dynamically verify if it has been relocated and if it is, it will calculate how far away it is from where it’s supposed to be, and calculate where in memory the QUEEN_INFO_HEADER structure ended up being.

Here’s the explanation why:

  • If the Queen was loaded into a different memory address, then the “call $+5” would put the exact memory address of the next instruction into the stack, so when you pop it into eax then substract from it the expected address 0xFFF40244, this means that eax will contain the offset from where it was supposed to be.
  • Above, we said eax would be equal to zero, yes, that’s true, but only in the usecase where the Queen is in the right memory address, as expected, otherwise, eax would simply contain the offset. Then you add to it 0xFFFF4023F which is the address of our function, and with the offset, that means eax now contains the exact memory address of the current function, wherever it was actually placed in RAM!
  • Then when it grabs the value 0x1AB (because that value is stored in RAM 15 bytes before the start of the function, that will work just fine) and substracts it from our current position, it gives us the address in RAM of the QUEEN_INFO_HEADER (because the compiler knows that the structure is located exactly 0x1AB bytes before the current function). This just makes everything be relative.

Isn’t that great!? 😉 It’s so simple, but it does require some thinking to figure out what it does and some thinking to understand why it does it that way… but then you end up with the problem of “How do I write this in C”? Honestly, I don’t know how, I just wrote this in my C file:

// Use Position-independent code to make this relocatable
void *get_queen_info_header() {
    return 0xFFF40094; 
}

I think the compiler takes care of doing all that magic on its own when you use the -fPIC compiler option (for gcc), which means “Position-Independent Code”.

What this means for Purism

On my side, I’ve finished reverse engineering the entry code—from the entry point all the way to the end of the function and all the subfunctions that it calls.

This only represents 9 functions however, and about 115 lines of C code; I haven’t yet fully figured out where exactly it’s going in order to execute the rest of the code. What happens is that the last function it calls (it actually jumps into it) grabs a variable from some area in memory, and within that variable, it will copy a value into the ESP, thus replacing our stack pointer, and then it does a “RETN”… which means that it’s not actually returning to the function that called it (coreboot), it’s returning… “somewhere”, depending on what the new stack contains, but I don’t know where (or how) this new stack is created, so I need to track it down in order to find what the return address is, find where the “retn” is returning us into, so I can unlock plenty of new functions and continue reverse engineering this.

I’ve already made some progress on that front (I know where the new stack tells us to return into) but you will have to wait until my next blog post before I can explain it all to you. It’s long and complicated enough that it needs its own post, and this one is long enough already.

Other stories from strange lands

You never really know what to expect when you start reverse engineering assembly. Here are some other stories from my past experiences.

  • I once spent a few days reverse engineering a function until about 30% of it when I finally realized that the function was… the C++ “+ operator” of the std::string class (which by the way, with the use of C++ templates made it excruciatingly hard to understand)!
  • I once had to reverse engineer over 5000 lines of assembly code that all resolved into… 7 lines of C code. The code was for creating a hash and it was doing a lot of manipulation on data with different values on every iteration. There was a LOT of xor, or, and, shifting left and right of data, etc., which took maybe a hundred or so lines of assembly and it was all inside a loop, which the compiler decided that—to optimize it—it would unravel the loop (this means that instead of doing a jmp, it will just copy-paste the same code again), so instead of having to reverse engineer the code once and then see that it’s a loop that runs 64 times, I had to reverse engineer the same code 64 times because it was basically getting copy-pasted by the compiler in a single block but the compiler was “nice” enough that it was using completely different registers for every repetition of the loop, and the data was getting shifted in a weird way and using different constants and different variables at every iteration, and—as if that wasn’t enough— every 1/4th of the loop, changing the algorithm and making it very difficult to predict the pattern, forcing me to completely reverse engineer the 5000+ assembly lines into C, then slowly refactor and optimize the C code until it became that loop with 7 lines of code inside it… If you’re curious you can see the code here at line 39, where there is some operation common to all iterations, then 4 different operations depending on which iteration we are doing, and the variables used for each operation changes after each iteration (P, PP, PPP and PPPP get swapped every time), and the constant values and the indices used are different for each iteration as well (see constants.h). It was complicated and took a long while to reverse engineer.
  • Below is the calling graph of the PS3 firmware I worked on some years ago. All of these functions have been entirely reverse engineered (each black rectangle is actually an entire function, and the arrows show which function calls which other function), and the result was the ps3xport tool. As you can see, sometimes a function can be challenging to reverse, and sometimes a single function can call so many nested functions that it can get pretty complicated to keep track of what is doing what and how everything fits together. That function at the top of the graph was probably very simple, but it brought with it so much complexity because of a single “call”:

Perseverance prevails

In conclusion:

  • Reverse engineering isn’t just about learning a new language, it’s a very different experience from “learning Java/Python/Rust after you’ve mastered C”, because of the way it works; it can sometimes be very easy and boring, sometimes it will be very challenging for a very simple piece of code.
  • It’s all about perseverance, being very careful (it’s easy to get lost or make a mistake, and very hard to track down and fix a mistake/typo if you make one), and being very patient. We’re talking days, weeks, months. That’s why reverse engineering is something that very few people do (compared to the number of people who do general software development). Remember also that our first example was 82 bytes of code, and the second one was only 19 bytes long, and most of the time, when you need to reverse engineer something, it’s many hundreds of KBs of code.

All that being said, the satisfaction you get when you finish reverse engineering some piece of code, when you finally understand how it works and can reproduce its functionality with open source software of your own, cannot be described with words. The feeling of achievement that you get makes all the efforts worth it!

I hope this write-up helps everyone get a fresh perspective on what it means to “reverse engineer the code”, why it takes so long, and why it’s rare to find someone with the skills, experience and patience to do this kind of stuff for months—as it can be frustrating, and we sometimes need to take a break from it and do something else in order to renew our brain cells.