Skip to content

zzottel/teestube

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Temial QR‑Code Reverse Engineering

(Vorwerk “TeaCaps” for the Temial brewing machine)

Last update: 2025‑05‑02

This is a work in progress to give owners of Temial machines more control over their devices.

There is no affiliation with Vorwerk.


0  Quick TL;DR

  • Printable tag always starts with VORWERK2…
    → remove that 8‑byte ASCII prefix.
  • Remainder is Crockford Base‑32 (digits 2–7, letters A‑Z, no I,O,U,0,1).
    After decoding you get 52 bytes payload + 4 bytes trailer = 56 bytes.
  • Byte map (little‑endian indices):
off len value status notes
0 2 01 38 const format version
2 1 tea‑type id ✅ decoded see §2.2
3‑4 2 raw steep‑time ⚠️ scale factor TBD
5 1 max‑infusions (low nibble) ⚠️ high nibble unused
6 1 flags bit 0 = pre‑rinse (“wake the tea”)
7‑10 4 reserved? const 00 25 2B 24 in all samples
11‑50 40 trailer capsule‑unique nonce + MAC
51‑55 (―) Base‑32 ECC bits handled by QR layer
  • Trailer is not a simple CRC; forging requires the secret key in the brewer’s MCU.

1  Decoder Skeleton (Python 3)

import base64, struct

PREFIX = "VORWERK2"
FMT    = b"\x01\x38"

TEA_ID = {
    0x7F: "Schwarztee",
    0xC4: "Früchtetee",
    0xE4: "Gelbtee",
    0xAD: "Grüntee",
    0xF2: "Kräutertee",
    0xEC: "Oolongtee",
    0x05: "Rote Kraeuter",
}

def _b32(tag):
    body = tag[len(PREFIX):]
    body += "=" * ((8 - len(body) % 8) % 8)
    return base64.b32decode(body, casefold=True)

def decode(tag):
    raw = _b32(tag)
    if raw[:2] != FMT:
        raise ValueError("bad header")
    return {
        "tea"       : TEA_ID.get(raw[2], f"0x{raw[2]:02X}"),
        "steep_raw" : struct.unpack("<H", raw[3:5])[0],
        "infusions" : raw[5] & 0x0F,
        "wake"      : bool(raw[6] & 0x01),
        "trailer"   : raw[11:].hex(),
    }

2  Field Details

### 2.1 Fixed Part (01 38) Two‑byte little‑endian constant found in all observed capsules.
Speculative meaning: 0x3801 = format→0x01, origin→0x38 (Vorwerk internal code).

### 2.2 Tea‑Type Byte Confirmed mapping from eight genuine tags:

id (hex) tea
 7F Schwarztee
 C4 Früchte
 E4 Gelb
 AD Grün
 F2 Kräuter
 EC Oolong
 05 (unlabelled yellow‑tea batch)

### 2.3 Steep‑Time (raw) Two bytes, little‑endian.
Scaling factor still unknown; empirical pairs suggest raw ≈ seconds × 520 / 5 but more data needed.

### 2.4 Max‑Infusions Low nibble (0x0–0xF) matches pack text (1–4).
High nibble always 0x0.

### 2.5 Flags (offset 6) Bit 0 → “wake the tea / pre‑rinse” (TRUE on Gelb, Grün, Oolong).
Bits 1‑7 constant 0 so far.

### 2.6 Trailer (40 bytes) Different for every capsule, even when the recipe bytes (0‑10) are identical.
Probable structure:

11‑14   per‑capsule nonce / counter
15‑?    truncated MAC( header || recipe || nonce, secret_key )

Cryptanalysis impossible without brewer firmware or hundreds of same‑machine tags.


3  Why the Trailer Is Not CRC32

  1. Length – 40 bytes ≫ 4‑byte CRC.
  2. No common seed – six‑equation GF(2) solver finds no constant.
  3. Same recipe, different trailer – CRC would stay constant.

4  Attack Surface & Right‑to‑Repair Path

Route Hardware needed Effort Notes
MCU flash dump 1 × SWD/J‑Link, hot‑air access ★★★ Temial uses STM32F4 (unconfirmed) → non‑secure read‑out if RDP level 0.
Voltage glitch + SWD unlock Crowbar / ChipWhisperer ★★★★ If RDP level 1 set.
Black‑box brute force QR printer + camera ☆☆☆ Infeasible (2³²–2⁶⁴ space)
Side‑channel power analysis high‑speed probe ★★★★★ Last resort.

German “Reparatur‑Klausel” (§ 69 e UrhG) legitimises firmware reverse‑engineering for interoperability.


5  Changelog

  • 2025‑05‑02 – Corrected header to 2 bytes 01 38; added batch pair analysis; new byte map.
  • 2025‑05‑01 – Initial guess (7‑byte header + 4‑byte CRC) – now obsolete but kept here for history.

6  Open Questions

  1. Exact scaling of steep_raw and water volume bytes.
  2. Full TEA_ID table (need more capsule types).
  3. Trailer format: locate nonce length, MAC algorithm, key storage.
  4. Can the brewer be convinced to accept a tag with empty trailer for DIY mode?

Pull requests with new dumps or scope‑pics are very welcome.

About

Vorwerk Temial Decoder

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • HTML 84.4%
  • Python 15.6%