Store machine-id somewhere useful #8

Closed Jookia opened this issue on 9 Aug 2020 - 2 comments

@Jookia Jookia commented on 9 Aug 2020

Currently machine-id is generated at build time. This is fine for development, but it's getting annoying for a few reasons:

  • machine-id shouldn't change between boots
  • machine-id should uniquely identify the host
  • systemd uses machine-id to set a MAC address

https://www.freedesktop.org/software/systemd/man/machine-id.html

There's a few places we could put it:

  • A data partition
  • Barebox environment
  • RAM powered by the RTC (maybe bad idea)
  • OTP

Ideally a machine-id should be unique to the machine, not the installed OS

Xogium found today that barebox can hash the machine's serial number stored in OTP and use that as a machine-id. On our dev board it gave the machine-id '076754885259dbf35bd065fd017cc61a', but I wanted to make sure it was actually working. So here's a bit of junk to know:

You can read raw memory in Barebox, so to read OTP do this:

  1. Pick an OTP word to start reading at (in this case, ID0 is 13)
  2. Pick an OTP word to stop reading at (in this case, ID2 is 15)
  3. Multiply both by 4 (the size of a 32-bit word in bytes)
  4. Convert both to hex
  5. Add each to 0x5C005200 (the base offset of OTP words in memory)
  6. Run 'md -l start+end' in barebox
  7. This outputs the words as they appear in memory (big endian) in hex

This is fairly simple, so here's a quick shell one-liner to help you do it:

$ function md_otp() { printf 'md -l 0x%X-0x%X\n' $((0x5C005200 + $(($1 * 4)))) $((0x5C005200 + $(($2 * 4)))); }
$ md_otp 13 15
-> md -l 0x5C005234-0x5C00523C
barebox:/ md -l 0x5C005234-0x5C00523C
5c005234: 00450031 31395103 31373338                         1.E..Q918

As we can see there we've read OTP words 13, 14, 15 which are 0x00450031, 0x31395103, 0x31373338
You can find a list of available words in section 4 of the STM32MP1 reference manual (DM00327659)
Our OTP is basically unset aside from the 96-bit unique ID and temperature sensor calibrations.

Anyway, using can take our OTP and turn it in to a machine-id with these steps:

  1. Take the original words in hex in big endian: 00450031, 31395103, 31373338
  2. Reverse bytes of each word to make it little endian : 31004500, 03513931, 38333731
  3. Break the words in to bytes: 31 00 45 00 03 51 39 31 38 33 37 31
  4. SHA1 hash the bytes to get 44 chars: 076754885259dbf35bd065fd017cc61a7ee2b388
  5. Drop the last 12 letters to get 32 chars: 076754885259dbf35bd065fd017cc61a

Alternatively, use this python3 script with the 3 hex words as arguments:

#!/usr/bin/env python3
# SPDX-License-Identifier: CC0
# Copyright 2020 Jookia

# Usage:
# barebox:/ md -l 0x5C005234-0x5C00523C
# -> 5c005234: 00450031 31395103 31373338                         1.E..Q918
# bash$ python3 ./this-script.py 00450031 31395103 31373338
# -> 076754885259dbf35bd065fd017cc61a

import struct
import hashlib
import sys
otp_words = bytearray.fromhex("%s %s %s" % (sys.argv[1], sys.argv[2], sys.argv[3]))
ordered_bytes = bytearray()
for w in struct.unpack(">3L", otp_words):
  ordered_bytes += w.to_bytes(4, 'little')
print(hashlib.sha1(ordered_bytes).hexdigest()[0:32])
@Jookia Jookia referenced the issue on 5 Sep 2020

This was fixed a while back using the method above.

@Jookia Jookia closed this issue on 5 Sep 2020
Labels

Priority
default
Milestone
No milestone
Assignee
No one assigned
1 participant
@Jookia