This is an automated email from the ASF dual-hosted git repository.

sjanc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit a15b17bc06ad29d11689b9b5b1ec469f16fa897e
Author: Szymon Janc <[email protected]>
AuthorDate: Tue Oct 6 19:25:31 2026 +0200

    mgmt/mcumgr: Add documentation and threat model
    
    This adds mcumgr README, SMP protocol and transport documentation and
    mcumgr security threat model from apache/mynewt-mcumgr repository.
    
    Documentation and threat model are updated to reflect that mcumgr is now
    part of Mynewt core: paths are updated, OS porting layer and Zephyr
    related statements are adjusted and remote shell execution is described
    as provided by sys/shell (SHELL_BRIDGE) as shell_mgmt was Zephyr only.
    Trust analysis itself is unchanged.
    
    Core THREAT_MODEL.md, SECURITY.md and AGENTS.md now refer to in-tree
    mcumgr threat model instead of apache/mynewt-mcumgr repository.
    
    Assisted-by: Claude:claude-opus-5-5
---
 AGENTS.md                         |   2 +-
 SECURITY.md                       |   3 +-
 THREAT_MODEL.md                   |  39 +--
 docs/os/modules/mcumgr/mcumgr.rst |  17 +-
 mgmt/mcumgr/README.md             | 107 ++++++++
 mgmt/mcumgr/THREAT_MODEL.md       | 527 ++++++++++++++++++++++++++++++++++++++
 mgmt/mcumgr/docs/protocol.md      | 277 ++++++++++++++++++++
 mgmt/mcumgr/docs/smp-bluetooth.md |  71 +++++
 mgmt/mcumgr/docs/smp-console.md   |  78 ++++++
 9 files changed, 1095 insertions(+), 26 deletions(-)

diff --git a/AGENTS.md b/AGENTS.md
index 5bf8538c7..aba264f5d 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -37,6 +37,6 @@ the in-model surface is memory safety in the 
externally-reachable parsers
 (`net/`, `mgmt/`, `fs/`, `encoding/`) and kernel objects reachable from
 input. Out of model: vendored Mbed-TLS internal CVEs (upstream's),
 protocol-spec weaknesses, the no-authentication management surface (modelled
-in `apache/mynewt-mcumgr`), and firmware-image authenticity (the
+in `mgmt/mcumgr/THREAT_MODEL.md`), and firmware-image authenticity (the
 bootloader's). The BLE radio surface is modelled in `apache/mynewt-nimble`.
 See the §11a known-non-findings list.
diff --git a/SECURITY.md b/SECURITY.md
index 458e1dd64..ea953b1a9 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -40,7 +40,8 @@ with no inter-component isolation, so the in-model surface is 
memory safety
 in the externally-reachable parsers (`net/`, `mgmt/`, `fs/`, `encoding/`)
 and kernel objects. Out of model are vendored Mbed-TLS internal CVEs
 (tracked via upstream), protocol-specification weaknesses, the
-no-authentication management surface (see the `apache/mynewt-mcumgr` model),
+no-authentication management surface (see the mcumgr model in
+`mgmt/mcumgr/THREAT_MODEL.md`),
 and firmware-image authenticity (enforced by the signature-verifying
 bootloader). The BLE radio surface is modelled in `apache/mynewt-nimble`.
 See `THREAT_MODEL.md` §9 and §11a.
diff --git a/THREAT_MODEL.md b/THREAT_MODEL.md
index 2699f0412..e5aa935cc 100644
--- a/THREAT_MODEL.md
+++ b/THREAT_MODEL.md
@@ -39,13 +39,14 @@
   billions of devices") *(documented: README)*.
 - **Repository / commit:** `apache/mynewt-core`, `master` @ `1dcb119ed885` 
(2026-06-09).
 - **Drafted:** 2026-06-13, ASF Security team (v0 draft from public artefacts).
-- **Companion repos this round:** `apache/mynewt-nimble` (the BLE stack —
-  its own model covers the radio surface) and `apache/mynewt-mcumgr` (the
-  SMP management library — its own model covers the SMP surface).
-  `mynewt-core` **hosts both**: it runs NimBLE and it ships its *own*
-  management stack under `mgmt/` (`newtmgr`, `smp`, `oicmgr`, `imgmgr`)
-  that is the same family as mcumgr. Where a surface is fully modelled in
-  a sibling document, this model points there rather than duplicating.
+- **Companion models:** `apache/mynewt-nimble` (the BLE stack — its own
+  model covers the radio surface) and mcumgr (the SMP management library,
+  `mgmt/mcumgr/THREAT_MODEL.md` — its own model covers the SMP surface).
+  mcumgr was moved into `mynewt-core` (`mgmt/mcumgr/`) from the former
+  `apache/mynewt-mcumgr` repository; the rest of the management stack
+  under `mgmt/` (`smp`, `oicmgr`, `imgmgr`) is the Mynewt glue around it.
+  Where a surface is fully modelled in a sibling document, this model
+  points there rather than duplicating.
 - **What triggers a revision:** a new network stack or protocol under
   `net/`; a new management transport or command group under `mgmt/`; a
   change to the boot/image-validation integration under `boot/`; a change
@@ -70,10 +71,10 @@ happens when they do.
 | --- | --- | --- | --- |
 | **Kernel** | `kernel/os` (scheduler, mempool, mbuf, mutex/sem, callout), 
`kernel/sim` | only *indirectly*, via input flowing up from net/mgmt | trusted 
core; a kernel memory bug reachable from untrusted input is critical (§8.1) |
 | **Network stacks** | `net/ip`, `net/oic` (OIC/CoAP), `net/lora` (LoRaWAN), 
`net/mqtt`, `net/wifi`, `net/cellular`, `net/osdp` | **yes — primary remote 
surface** | each is an untrusted-wire/radio parser (§6) |
-| **Management** | `mgmt/{newtmgr,smp,oicmgr,imgmgr,mgmt,image_header}` | 
**yes** | same family as `apache/mynewt-mcumgr`; **see that model** for the SMP 
trust analysis. No authn/authz by design (§9) |
+| **Management** | `mgmt/{mcumgr,newtmgr,smp,oicmgr,imgmgr,mgmt,image_header}` 
| **yes** | mcumgr; **see `mgmt/mcumgr/THREAT_MODEL.md`** for the SMP trust 
analysis. No authn/authz by design (§9) |
 | **Crypto** | `crypto/mbedtls` (**vendored upstream**) | as a library, by the 
code above | primitives; mbedtls security is upstream's (§3, §11a). tinycrypt 
was **removed** from core before the 1.15 releases *(maintainer)* |
 | **Boot / image** | `boot/{split,split_app,startup,stub}`, 
`mgmt/image_header` | at boot, over the staged image | image *authenticity* 
gate is the signature-verifying bootloader (MCUboot); see §9/§10 |
-| **Sys / local mgmt** | 
`sys/{console,shell,config,log,coredump,fault,reboot,mfg,flash_map,stats,id}` | 
`console`/`shell` = local serial surface; also reachable remotely via 
`shell_mgmt` over SMP | local management surface (§6, §11) |
+| **Sys / local mgmt** | 
`sys/{console,shell,config,log,coredump,fault,reboot,mfg,flash_map,stats,id}` | 
`console`/`shell` = local serial surface; also reachable remotely via 
`SHELL_BRIDGE` over SMP | local management surface (§6, §11) |
 | **Filesystems** | `fs/*` (nffs, fatfs, littlefs ports) | via on-flash 
structures / file content | on-flash parser robustness (§6) |
 | **Encoding** | `encoding/*` (tinycbor, json, base64, …) | by every layer 
that decodes untrusted data | untrusted-deserialization primitives (§6) |
 | **HAL / BSP / drivers** | `hw/*` | sensor/peripheral input | per-driver. 
**Upstream-supported in-tree BSPs/drivers are in scope**; board hardware itself 
and out-of-tree BSPs are not (§3.3) *(maintainer)* |
@@ -121,8 +122,8 @@ happens when they do.
 4. **`apps/`, `test/`, demo targets** — example and test code, not the
    library's production runtime.
 5. **The SMP/management *protocol* trust analysis** — fully covered in
-   `apache/mynewt-mcumgr`'s model; not duplicated here (this model only
-   notes that `mgmt/` is the same family and inherits its §9).
+   mcumgr's model (`mgmt/mcumgr/THREAT_MODEL.md`); not duplicated here
+   (this model only notes that `mgmt/` inherits its §9).
 6. **The BLE radio surface** — covered in `apache/mynewt-nimble`'s model.
 7. **Physical / invasive / side-channel and supply-chain** concerns.
 
@@ -178,7 +179,8 @@ selection. Load-bearing variants:
   IP attack surface; an OIC/CoAP or LoRaWAN build does). *(documented:
   per-package `syscfg.yml`)*
 - **Which `mgmt/` transports/groups are enabled** (newtmgr vs SMP vs
-  oicmgr; `shell_mgmt` reachable remotely). Inherits mcumgr's §5a.
+  oicmgr; shell exec via `SHELL_BRIDGE` reachable remotely). Inherits
+  mcumgr's §5a.
 - **Crypto backend** (`crypto/mbedtls`) and its cipher/verification
   configuration. *(maintainer — §14 Q3; tinycrypt is gone from core)*
 - **RNG source.** Mynewt provides **no unified random API**. Consumers use
@@ -189,7 +191,7 @@ selection. Load-bearing variants:
 - **Secure-boot integration** (`boot/` split/stub) and whether image
   signature verification is enabled. *(maintainer — §14 Q2, confirmed)*
 - **`sys/shell` over console and/or over mgmt** — a powerful local/remote
-  surface when enabled. *(documented: `sys/shell`, `cmd/shell_mgmt`)*
+  surface when enabled. *(documented: `sys/shell` `SHELL_BRIDGE`)*
 - **`sys/coredump` / `sys/fault`** may expose memory state; they are
   intentional diagnostics for the integrator to gate.
   *(maintainer — §14 Q5, confirmed)*
@@ -208,8 +210,8 @@ this v0 cannot have read every parser).
 | **LoRaWAN** join/data | `net/lora` | anyone in radio range | MIC/join-nonce 
handling; safe MAC-command parse; replay posture per spec *(inferred — §14 Q8)* 
|
 | MQTT broker responses | `net/mqtt` | the broker / a MITM | safe 
CONNACK/PUBLISH/variable-length parse *(inferred — §14 Q9)* |
 | **OSDP** messages | `net/osdp` | a peer on the RS-485/serial bus 
(physical-access-control context!) | safe message parse; SCBK/secure-channel 
correctness *(inferred — §14 Q10)* |
-| SMP / newtmgr / oic mgmt frames | `mgmt/*` | a peer on the mgmt transport | 
**see `apache/mynewt-mcumgr` §6**; no authn/authz by design |
-| Console / shell input | `sys/console`, `sys/shell` | local serial (or remote 
via `shell_mgmt`) | bounded line handling; shell is powerful-by-design (§11) |
+| SMP / newtmgr / oic mgmt frames | `mgmt/*` | a peer on the mgmt transport | 
**see `mgmt/mcumgr/THREAT_MODEL.md` §6**; no authn/authz by design |
+| Console / shell input | `sys/console`, `sys/shell` | local serial (or remote 
via `SHELL_BRIDGE`) | bounded line handling; shell is powerful-by-design (§11) |
 | On-flash filesystem structures | `fs/*` | whoever can write flash / supply 
an image | safe parse of corrupt/hostile on-flash metadata *(inferred — §14 
Q11)* |
 | CBOR / JSON / base64 payloads | `encoding/*` | every caller above | bounded, 
memory-safe decode of malicious encodings *(inferred — §14 Q12)* |
 | Staged firmware image | `mgmt/image_header`, `boot/` | the mgmt peer | safe 
image-header parse; **execution gated by MCUboot signature check, not by 
Mynewt** *(inferred — §14 Q2)* |
@@ -311,7 +313,7 @@ plumbing, so the properties are mostly *robustness* 
properties; the
 2. **Expose only the `net/` stacks and `mgmt/` transports the product
    needs**, and gate each (link encryption, network segmentation, BLE
    bonding via nimble) per §10 of the relevant sibling model.
-3. **Keep `sys/shell` / `shell_mgmt` / `coredump` out of production**
+3. **Keep `sys/shell` / `SHELL_BRIDGE` / `coredump` out of production**
    unless required and access-gated.
 4. **Track upstream advisories for every vendored component** — not just
    mbedtls, but each package pulled in through a `repository.<name>`
@@ -325,7 +327,7 @@ plumbing, so the properties are mostly *robustness* 
properties; the
 
 ## §11 Known misuse patterns
 
-- Shipping with `shell_mgmt`/`sys/shell` reachable over an open transport.
+- Shipping with `SHELL_BRIDGE`/`sys/shell` reachable over an open transport.
 - Leaving image-signature verification off "to make updates easier".
 - Exposing an OIC/CoAP or MQTT service on an open network and assuming the
   protocol authenticates the peer.
@@ -419,7 +421,8 @@ against a fully-malicious peer, and has it been fuzzed?)
   → **Partly.** `apps/`, `test/` and demo `targets/` are out, but
   **upstream-supported BSPs and in-tree drivers under `hw/` are IN
   scope** (§3.3). The in-tree `mgmt/` surface is read against the
-  `apache/mynewt-mcumgr` model rather than re-analysed here.
+  mcumgr model (`mgmt/mcumgr/THREAT_MODEL.md`) rather than re-analysed
+  here.
 
 **Meta — ANSWERED**
 - **Q17.** OK for this `THREAT_MODEL.md` to be the canonical model,
diff --git a/docs/os/modules/mcumgr/mcumgr.rst 
b/docs/os/modules/mcumgr/mcumgr.rst
index 78c06a0ef..495b9470c 100644
--- a/docs/os/modules/mcumgr/mcumgr.rst
+++ b/docs/os/modules/mcumgr/mcumgr.rst
@@ -4,13 +4,18 @@ MCU Manager (mcumgr)
 .. toctree::
    :maxdepth: 1
 
-mcumgr, a derivative of newtmgr, is a device/image/embedded OS  management 
library with pluggable transport and encoding components and is, by design, 
operating system and hardware independent. It relies on hardware porting layers 
from the operating system it runs on. Currently, mcumgr runs on both the Apache 
Mynewt and Zephyr operating systems.
+mcumgr, a derivative of newtmgr, is the device management library of Apache 
Mynewt. It implements the device side of
+the management protocol and provides command handlers for image, file system, 
log, statistics and OS management. mcumgr
+is located in ``mgmt/mcumgr`` directory of the ``apache-mynewt-core`` 
repository. Previously it was maintained in a
+separate ``mynewt-mcumgr`` repository with an OS abstraction layer.
 
-So how is it different from newtmgr? There is one substantial difference 
between the two: newtmgr supports two wire formats - NMP (plain newtmgr 
protocol) and OMP (CoAP newtmgr protocol).  mcumgr only supports NMP (called 
"SMP" in mcumgr).
+Two wire formats are supported:
 
-NMP is a simple binary format: 8-byte header plus CBOR payload
-OMP uses CoAP requests to the `/omgr` CoAP resource
+- SMP (Simple Management Protocol, previously called NMP): simple binary 
format with 8-byte header plus CBOR payload
+- OMP: SMP requests sent as CoAP requests to the ``/omgr`` CoAP resource (see 
``mgmt/oicmgr``)
 
-A request has the same effect on the receiving device regardless of wire 
format, but OMP fits more cleanly in a system that is already using CoAP. 
Documentation on mcumgr can be found in the source code repository: 
`mynewt-mcumgr <https://github.com/apache/mynewt-mcumgr>`_
+A request has the same effect on the receiving device regardless of wire 
format, but OMP fits more cleanly in a system
+that is already using CoAP.
 
-There has been some discussion about combining all this functionality into a 
single library (mcumgr). Your views are welcome on [email protected]. 
+Protocol and transport documentation can be found in ``mgmt/mcumgr/docs`` 
directory and an example application is
+available in ``apps/smp_svr``.
diff --git a/mgmt/mcumgr/README.md b/mgmt/mcumgr/README.md
new file mode 100644
index 000000000..5532c8a44
--- /dev/null
+++ b/mgmt/mcumgr/README.md
@@ -0,0 +1,107 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+
+# mcumgr
+
+mcumgr is the device management library of Apache Mynewt. It implements the
+device side (server) of SMP (Simple Management Protocol) and provides
+handlers for core management commands: image management, file system
+management, log management, statistics and OS management.
+
+mcumgr was developed in the separate `apache/mynewt-mcumgr` repository (based
+on Mynewt newtmgr code) with an OS abstraction layer so that it could also be
+used by other operating systems. It is now part of Apache Mynewt core again and
+uses Mynewt APIs directly.
+
+## Architecture
+
+The mcumgr stack has the following layout:
+
+```
++---------------------+---------------------+
+|             <command handlers>            |
++---------------------+---------------------+
+|                   mgmt                    |
++---------------------+---------------------+
+|           <transfer encoding(s)>          |
++---------------------+---------------------+
+|               <transport(s)>              |
++---------------------+---------------------+
+```
+
+* *Command handler*: Processes incoming mcumgr requests and generates
+  corresponding responses. A command handler is associated with a single
+  command type, defined by a (group ID, command ID) pair.
+* *mgmt*: The core of mcumgr; facilitates the passing of requests and responses
+  between the command handlers and the transports and transfer encodings.
+* *Transfer encoding*: Defines how mcumgr requests and responses are encoded on
+  the wire: SMP or OMP (SMP over CoAP).
+* *Transport*: Sends and receives mcumgr packets over a particular medium.
+
+## Packages
+
+- `mgmt/mcumgr/mgmt`: management core; group registration and dispatch.
+- `mgmt/mcumgr/smp`: Simple Management Protocol transfer encoding.
+- `mgmt/mcumgr/omp`: OIC Management Protocol (SMP over CoAP) transfer
+  encoding, used by `mgmt/oicmgr`.
+- `mgmt/mcumgr/cmd/img_mgmt`: image management command handlers.
+- `mgmt/mcumgr/cmd/fs_mgmt`: file system command handlers.
+- `mgmt/mcumgr/cmd/log_mgmt`: log management command handlers.
+- `mgmt/mcumgr/cmd/os_mgmt`: OS management command handlers.
+- `mgmt/mcumgr/cmd/stat_mgmt`: statistics command handlers.
+- `mgmt/mcumgr/util`: utility functions.
+- `encoding/cborattr`: used for parsing incoming mcumgr requests.
+
+SMP transports are provided by `mgmt/smp/transport/ble`,
+`mgmt/smp/transport/smp_shell` and `mgmt/smp/transport/smp_uart`. Other
+packages provide additional command groups, e.g. `sys/config` (config
+management), `sys/shell` (shell command execution) and `mgmt/imgmgr`.
+
+## Configuration
+
+To use mcumgr, an application needs to depend on an SMP transport and on the
+command handlers it wants to expose, e.g.:
+
+```
+    - '@apache-mynewt-core/mgmt/smp/transport/ble'
+    - '@apache-mynewt-core/mgmt/smp/transport/smp_shell'
+    - '@apache-mynewt-core/mgmt/mcumgr/cmd/fs_mgmt'
+    - '@apache-mynewt-core/mgmt/mcumgr/cmd/img_mgmt'
+    - '@apache-mynewt-core/mgmt/mcumgr/cmd/os_mgmt'
+    - '@apache-mynewt-core/mgmt/mcumgr/smp'
+```
+
+For an example application see `apps/smp_svr` (SMP) and `apps/omp_svr` (OMP).
+
+Image management requires the MCUboot boot loader.
+
+## Documentation
+
+- [SMP protocol](docs/protocol.md)
+- [SMP over console](docs/smp-console.md)
+- [SMP over Bluetooth](docs/smp-bluetooth.md)
+- [Security threat model](THREAT_MODEL.md)
+
+## Command line tool
+
+The `mcumgr` command line tool is available at
+https://github.com/apache/mynewt-mcumgr-cli. `newtmgr`
+(https://github.com/apache/mynewt-newtmgr) can be used as well.
diff --git a/mgmt/mcumgr/THREAT_MODEL.md b/mgmt/mcumgr/THREAT_MODEL.md
new file mode 100644
index 000000000..ec4c3d81c
--- /dev/null
+++ b/mgmt/mcumgr/THREAT_MODEL.md
@@ -0,0 +1,527 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+
+# Apache mcumgr Security Threat Model (draft)
+
+> **Status: v0, reviewed by the PMC.** This document was drafted by the
+> ASF Security team from public artefacts (the in-repo `README.md`,
+> `protocol.md`, `transport/*.md`, and the `cmd/*/syscfg.yml` defaults)
+> against the Scovetta threat-model rubric. **Szymon Janc (Mynewt PMC)
+> reviewed it on 2026-07-27** and answered the core-protocol, build-time,
+> scope and meta questions in §14; his answers are folded into the body.
+> Every non-trivial claim carries a provenance tag — *(documented)*
+> (stated in the repo's own files), *(maintainer)* (ratified or corrected
+> by a PMC member), or *(inferred)* (reasoned from code structure /
+> domain knowledge, and routed to a numbered question in §14). The
+> remaining *(inferred)* claims are the per-handler robustness questions;
+> corrections are still welcome on any of them.
+>
+> **Moved into `apache/mynewt-core`.** This model was written for the
+> `apache/mynewt-mcumgr` repository. mcumgr has since been moved into
+> `apache/mynewt-core` (`mgmt/mcumgr/`) and its OS porting layer, Zephyr
+> support and `shell_mgmt` were removed. Paths and porting-layer remarks
+> below are updated accordingly; the trust analysis itself is unchanged.
+
+## §1 Header
+
+- **Project:** Apache mcumgr — a management library for 32-bit MCUs.
+- **Repository / commit:** originally `apache/mynewt-mcumgr`, `master` @ 
`0b63bc54308b` (2026-05-20); now `apache/mynewt-core` `mgmt/mcumgr/`.
+- **Drafted:** 2026-06-13, by the ASF Security team (v0 draft from public 
artefacts).
+- **Companion models:** `apache/mynewt-core`'s top-level
+  `THREAT_MODEL.md` (the RTOS mcumgr is now part of) and
+  `apache/mynewt-nimble` (the BLE stack that provides one of mcumgr's
+  transports). mcumgr is Mynewt-only and uses Mynewt APIs directly; Zephyr
+  **forked mcumgr into its own tree**, so its divergences are out of model
+  here. *(maintainer — §14 Q4, Q19)* Where a property is delegated to the
+  host OS or the bootloader, that is called out explicitly.
+- **What should trigger a revision of this model:** a new SMP command
+  group; a new transport; the addition of any authentication /
+  authorization layer to SMP; a change to which command groups are
+  compiled in by default; or a change to how uploaded images are gated
+  before execution. Internal refactors that do not change the wire
+  protocol, the command surface, or the trust boundary do **not** require
+  a revision.
+
+## §2 Scope and intended use
+
+mcumgr is **a library that a device-firmware author integrates into a
+product**, not a standalone application. It implements the device-side
+(**server**) half of **SMP — the Simple Management Protocol** — plus a
+set of management command handlers and pluggable transports. The remote
+(**client**) half is a separate tool (`mcumgr-cli` / `newtmgr`, in other
+repos) or a mobile/desktop app; it is **out of this model's scope** (and
+was explicitly declined from this review round by the PMC). *(documented:
+README; maintainer scope decision on the PMC's private list)*
+
+**Intended deployment.** mcumgr is compiled into the firmware image of an
+embedded device and exposed over one or more transports so that an
+operator (or a provisioning/field-update tool) can manage the device:
+upload new firmware, inspect state, read/write files, reset it. The
+canonical use is **device firmware update (DFU)** and field diagnostics.
+*(documented: README, `mgmt/mcumgr/cmd/img_mgmt`)*
+
+### Component families (each modelled at its own trust/surface level)
+
+| Family | Directories | What it does | Surface |
+| --- | --- | --- | --- |
+| **SMP core** (frame + dispatch) | `mgmt/mcumgr/{smp,mgmt,omp}/`, Mynewt glue 
in `mgmt/smp/`, `mgmt/oicmgr/` | Parses the `mgmt_hdr` frame header, dispatches 
by `(group, id)`, decodes the CBOR payload, encodes the response. | The whole 
untrusted-input parse path — every byte after the transport hands a frame up. |
+| **Command handlers** | `mgmt/mcumgr/cmd/{img,fs,os,log,stat}_mgmt`; other 
groups outside `mgmt/mcumgr/`: `sys/config` (config), `sys/shell` 
(`SHELL_BRIDGE`, shell exec), `mgmt/smp/smp_os`, `mgmt/imgmgr`, 
`test/crash_test`, `test/runtest` | Implement individual commands within their 
group. Each has a **very different** privilege footprint (firmware write vs. 
read a stat). | Per-command; see §6 / §11. |
+| **Transports** | `mgmt/smp/transport/{ble,smp_shell,smp_uart}` (specs: 
`mgmt/mcumgr/docs/smp-bluetooth.md`, `mgmt/mcumgr/docs/smp-console.md`), OIC 
transports of `net/oic` for OMP | Carry SMP frames between client and server. | 
The reachability boundary — *who* can deliver a frame at all. |
+| **CBOR / attr decode** | `encoding/cborattr/`, `encoding/tinycbor/` | 
Decodes attacker-controlled CBOR payloads into C structs. | Classic 
untrusted-deserialization surface. |
+| **Ships-but-context-dependent** | `apps/smp_svr`, `apps/omp_svr` | Example 
apps. | Demo / integration code; modelled as the integrator's, not the 
library's, per §3. |
+
+### What mcumgr is *not*
+
+- It is **not** a secure channel. It provides **no** authentication,
+  authorization, confidentiality, integrity, or replay protection at the
+  SMP layer (see §9). *(maintainer — §14 Q1, confirmed)*
+- It is **not** the thing that decides whether an uploaded image is
+  allowed to *run*. mcumgr **stages** an image into a secondary slot; a
+  separate bootloader (**MCUboot**, in `apache/mynewt-core`'s `boot/`)
+  verifies the signature and decides whether to boot it. *(documented:
+  README; §14 Q2)*
+- It is **not** a portable library anymore — it is part of Mynewt core and
+  uses Mynewt APIs (flash, mbufs, sysinit) directly. Zephyr forked mcumgr
+  into its own tree. *(maintainer — §14 Q4)*
+
+## §3 Out of scope (explicit non-goals)
+
+1. **The SMP client** (`mcumgr-cli`, `newtmgr`, mobile apps). Separate
+   repos; declined from this round. A finding that requires a malicious
+   *client* is in-model only insofar as it is *the server* mishandling a
+   crafted frame (that is §6, and in scope) — the client's own code is
+   out.
+2. **Transport link security** — BLE pairing/bonding/encryption, serial
+   physical access control, UDP network reachability. That is the
+   transport's and the integrator's responsibility (§10), and for BLE
+   specifically it lives in `apache/mynewt-nimble`'s Security Manager,
+   not here.
+3. **Image authenticity / secure boot.** Whether an uploaded image is
+   signed, and whether an unsigned image can execute, is **MCUboot's**
+   job (`apache/mynewt-core` `boot/`). mcumgr's role ends at writing
+   bytes to the staging slot. *(documented: README; §14 Q2)*
+4. **The rest of the RTOS.** Flash drivers, the scheduler, the HAL, `os_`
+   primitives — modelled in `apache/mynewt-core`'s top-level
+   `THREAT_MODEL.md`. mcumgr assumes they are correct (§5).
+   *(maintainer — §14 Q4)*
+5. **Zephyr and its fork.** Zephyr maintains its own fork of mcumgr in
+   the Zephyr tree. Zephyr-only features and divergences are out of model
+   here.
+   *(maintainer — §14 Q4, Q19)*
+6. **The integrating firmware author** — trusted by construction. mcumgr
+   has no concept of a "user"; it has a remote *peer* on a transport, and
+   that peer's trust level is entirely a property of the transport the
+   integrator chose to expose (§7).
+7. **Physical / invasive attacks** — chip decap, fault injection, bus
+   probing, glitching the boot. Out of model.
+8. **Supply-chain / build hygiene** — action pinning, release signing,
+   dependency currency. Not a threat-model concern.
+
+## §4 Trust boundaries and data flow
+
+There is exactly **one trust boundary that matters**: the point where a
+transport hands an SMP frame up to the SMP core. Everything the firmware
+already contains (handlers, the CBOR decoder, the flash routines) is in a
+**single trust domain** — one address space, no privilege separation, no
+MMU isolation between command groups *(inferred: embedded RTOS model —
+§14 Q3)*.
+
+```
+            UNTRUSTED                          |   TRUSTED (firmware image)
+                                               |
+ attacker in radio range / on serial / on net |
+        |                                      |
+        v   raw SMP frame (mgmt_hdr + CBOR)    |
+  [ transport RX ] --------------------------> | [ SMP core: parse mgmt_hdr ]
+        (BLE / console / UDP)                  |        |
+                                               |        v  dispatch (group,id)
+                                               | [ command handler ]
+                                               |   img/fs/os/log/stat/shell
+                                               |        |
+                                               |        v  decode CBOR payload
+                                               | [ cborattr / tinycbor ]
+                                               |        |
+                                               |        v
+                                               | flash write (image slot) /
+                                               | file read-write / reset /
+                                               | stats read / shell exec
+```
+
+The trust transition is **frame ingress**. After that point there is no
+further internal boundary: a handler that the integrator compiled in can
+do whatever that command does, to whoever can send the frame. The
+security of the system therefore rests almost entirely on **who can put a
+frame on an enabled transport** (§7, §10) — not on anything SMP itself
+checks.
+
+## §5 Assumptions about the environment
+
+- **32-bit MCU, single physical address space, no process isolation, no
+  user/kernel split.** A memory-safety violation in any handler is a
+  whole-device compromise, not a contained one. *(inferred — §14 Q3)*
+- **The Mynewt services mcumgr uses are correct** — flash read/write/erase,
+  mbufs, the SMP transport driver. mcumgr's guarantees are conditional on
+  these. *(§14 Q4)*
+- **For image execution to be gated, MCUboot (or an equivalent
+  signature-verifying bootloader) is present and configured to reject
+  unsigned/untrusted images.** Without that, "upload an image" becomes
+  "run arbitrary code" — but that is a deployment property, not an
+  mcumgr property. *(documented: README; §14 Q2)*
+- **The firmware author chose which transports to expose and which
+  command groups to compile in.** mcumgr does not pick these. *(documented:
+  per-package `syscfg.yml`)*
+
+## §5a Build-time and configuration variants
+
+mcumgr's attack surface is **defined at build time** by which command
+groups are linked in and how they are configured. This section is
+load-bearing: the same library is benign or dangerous depending on these
+choices.
+
+- **Which command groups are compiled in.** `img_mgmt`, `fs_mgmt`,
+  `os_mgmt`, `log_mgmt`, `stat_mgmt` are separate packages; remote shell
+  command execution is provided by `sys/shell` (`SHELL_BRIDGE`).
+  Remote shell execution and `fs_mgmt` (arbitrary file read/write) are
+  the highest-power groups and should be off in most production builds.
+  **On Mynewt there is no meaningful "default" set.** What is compiled in
+  follows from which packages the application — or a system component —
+  pulls in, which is a per-sample configuration choice. The rule of thumb
+  is that a group must be **explicitly enabled by the user**, either
+  directly in the app or transitively by pulling a package that depends
+  on it (enabling USB, for instance, may pull `img_mgmt`). So "is it on by
+  default?" is the wrong question to ask of this repo; "which packages
+  does this product's build pull in?" is the right one.
+  *(maintainer — §14 Q5)*
+- **Upload chunk buffers are stack-allocated.**
+  `IMG_MGMT_UL_CHUNK_SIZE` and `FS_MGMT_UL_CHUNK_SIZE` default to **512**
+  and the syscfg descriptions state "a buffer of this size gets
+  allocated **on the stack** during handling of an upload." The handler
+  must therefore validate the attacker-supplied chunk length against this
+  bound *before* copying — a classic embedded stack-overflow sink if the
+  check is wrong or missing. *(documented: 
`mgmt/mcumgr/cmd/img_mgmt/syscfg.yml`,
+  `mgmt/mcumgr/cmd/fs_mgmt/syscfg.yml`; §14 Q6)*
+- **`FS_MGMT_PATH_SIZE` (default 64)** bounds the file-path buffer for
+  `fs_mgmt`. Path handling against this bound, and any path-traversal
+  containment, is a per-build concern. *(documented: 
`mgmt/mcumgr/cmd/fs_mgmt/syscfg.yml`;
+  §14 Q7)*
+- **Frame endianness.** SMP adds optional little-endian support on top of
+  NMP's mandatory big-endian header. Both decode paths are reachable.
+  *(documented: `protocol.md`)*
+- **`img_mgmt` "dummy header" / direct-image-upload toggles** appear in
+  syscfg and change behaviour; their security relevance needs maintainer
+  input. *(documented: `mgmt/mcumgr/cmd/img_mgmt/syscfg.yml`; §14 Q8)*
+
+## §6 Assumptions about inputs
+
+The **only** untrusted input is the **SMP frame** delivered by a
+transport. If the attacker can reach an enabled transport, **every byte
+of the frame is attacker-controlled** — header and payload alike.
+
+### SMP frame header trust table (`struct mgmt_hdr`)
+
+| Field | Meaning | Attacker-controllable? | Handler/core must enforce |
+| --- | --- | --- | --- |
+| `nh_op` (3 bits) | READ / WRITE / *_RSP | **yes** | reject/ignore response 
opcodes arriving at a server; route only valid ops *(inferred — §14 Q9)* |
+| `nh_flags` | reserved | **yes** | defined-bit validation; ignore reserved 
bits safely *(documented: "TBD"; §14 Q9)* |
+| `nh_len` | **claimed** payload length | **yes** | the claimed length must be 
validated against the *actually received* byte count and against buffer bounds 
before use — never trusted as the copy size *(inferred — §14 Q10)* |
+| `nh_group` | command group selector | **yes** | dispatch only to a 
registered group; unknown group → clean error, not UB *(inferred — §14 Q11)* |
+| `nh_seq` | sequence number | **yes** | no replay/ordering guarantee is 
claimed (§9); used only to correlate response *(documented: "TBD"; §14 Q12)* |
+| `nh_id` | command within group | **yes** | dispatch only to a registered 
handler; unknown id → clean error *(inferred — §14 Q11)* |
+
+### CBOR payload trust table (per high-value command)
+
+| Command group → command | Attacker-supplied fields | What the handler does 
with them | Must enforce |
+| --- | --- | --- | --- |
+| `img_mgmt` upload | image `data` chunk, `off`(set), `len`, `sha` | copies 
`data` into a **stack** buffer, writes it to the staging flash slot at `off` | 
`len`/chunk-size validated vs `IMG_MGMT_UL_CHUNK_SIZE` *before* copy; `off` 
monotonic / bounded to slot size; **never** treat acceptance as "this image is 
trusted" (that is MCUboot, §3.3) *(documented + inferred — §14 Q6)* |
+| `fs_mgmt` upload/download | file `name`/path, `off`, `data`, `len` | opens a 
file at `name`, reads/writes at `off` | path bounded to `FS_MGMT_PATH_SIZE`; 
**path-traversal containment** to an intended directory (or the integrator 
accepts full-FS access); chunk bound as above *(inferred — §14 Q7)* |
+| `os_mgmt` taskstat / mpstat / datetime / reset | command params | returns 
task/memory diagnostics; performs a device reset | bounded output encoding; 
reset only after the documented delay *(documented: reset delay syscfg)* — note 
these **leak internal state** and **reboot the device** to anyone on the 
transport, by design *(inferred — §14 Q13)* |
+| shell exec (`sys/shell`, `SHELL_BRIDGE`) | a shell command line | executes 
it in the device shell | **this is arbitrary command execution by design** when 
the group is compiled in; intended for trusted/dev contexts only *(inferred — 
§14 Q5/Q14)* |
+
+### Size / shape / rate
+
+- **CBOR depth/size.** The payload is CBOR decoded by the bundled
+  tinycbor/`cborattr`. Robustness against deeply-nested, truncated, or
+  oversized CBOR is the decoder's job; whether mcumgr caps nesting/size
+  before decode is unknown to us. *(inferred — §14 Q15)*
+- **No SMP-layer rate limiting.** mcumgr does not rate-limit inbound
+  frames; backpressure is the transport's. *(inferred — §14 Q16)*
+
+## §7 Adversary model
+
+### Actors
+
+| Actor | In scope? | Capabilities |
+| --- | --- | --- |
+| **Anyone who can deliver an SMP frame over an *enabled* transport** | **yes 
— the primary adversary** | craft arbitrary SMP frames (any group/id/len, any 
CBOR), replay, flood, fuzz. For BLE: in radio range (bounded by whatever link 
security the integrator enabled in nimble — possibly none). For serial: 
physical/console access. For UDP: network reachability. |
+| **A malformed-but-deliverable frame from an otherwise "legitimate" client** 
(buggy or compromised management tool) | **yes — parser robustness must hold** 
| drives the server's parse/dispatch/decode path with adversarial bytes; 
in-model for memory safety, hang, unbounded stack/heap use. |
+| **The transport's link-layer peer** (e.g. a paired BLE central) | 
**conditionally** | if the integrator required BLE bonding+encryption, the 
adversary is reduced to a *bonded* peer; if not, it is anyone in range. The 
*reduction* is the integrator's doing, not mcumgr's (§10). |
+| **The integrating firmware author** | **out of scope** | trusted; chooses 
transports, enabled groups, and the bootloader policy. |
+| **Physical-invasive attacker** (glitch, decap, bus probe) | **out of scope** 
| §3.6. |
+| **Side-channel observer** | **out of scope** *(inferred — §14 Q17)* | no 
constant-time or side-channel-resistance claim is made by mcumgr. |
+
+### The defining asymmetry
+
+Because SMP performs **no authentication or authorization** (§9), the
+adversary's power is **entirely determined by transport reachability and
+the set of enabled command groups** — not by anything mcumgr checks. A
+device that exposes `img_mgmt` + `fs_mgmt` + shell exec over an
+unencrypted, un-bonded BLE connection is, by design, **fully controllable
+by anyone in radio range**. This is not a vulnerability in mcumgr; it is
+the integrator operating mcumgr outside its intended trust assumptions
+(§10, §11). Conversely, a memory-safety bug in the frame parser **is**
+mcumgr's, because it breaks even when the transport is perfectly secured.
+
+## §8 Security properties the project provides
+
+For each: condition, violation symptom, severity, provenance. The list is
+deliberately short — mcumgr is a thin protocol server, and most security
+properties of a deployed device are delegated to the transport, the
+bootloader, and the integrator (§10).
+
+1. **Memory-safe parsing and dispatch of SMP frames on the compiled-in
+   command groups, given correct underlying Mynewt services.** *(inferred — 
§14 Q10/Q11; this is the single most important property to confirm or qualify)*
+   - *Violation symptom:* a crafted frame (bad `nh_len`, oversized upload
+     chunk, malformed CBOR, unknown group/id) causes out-of-bounds
+     read/write, stack overflow, or controlled corruption.
+   - *Severity:* **high** — single address space, so corruption is
+     whole-device (§5).
+2. **Bounded stack use during uploads, when chunk length is validated
+   against `*_UL_CHUNK_SIZE`.** *(documented config + inferred enforcement — 
§14 Q6)*
+   - *Violation symptom:* an upload chunk larger than the configured
+     bound overruns the stack buffer.
+   - *Severity:* **high**.
+3. **Faithful implementation of the SMP wire format** (header layout,
+   op/group/id semantics, CBOR encoding of responses). *(documented: 
protocol.md)*
+   - *Violation symptom:* a response that misencodes lengths/IDs such
+     that a conforming client mis-parses it.
+   - *Severity:* **low–medium** (interop / client-side, mostly).
+4. **Clean rejection of unknown groups/commands** (no dispatch into
+   unregistered handlers). *(inferred — §14 Q11)*
+   - *Violation symptom:* an unknown `(group,id)` reaches uninitialised
+     function state.
+   - *Severity:* **medium–high**.
+
+mcumgr explicitly does **not** appear to claim graceful behaviour under
+*resource exhaustion* (flooding) or any property about *malicious but
+well-formed* commands (those are §9/§10, by design).
+
+## §9 Security properties the project does *not* provide
+
+This is the most important section for triage, because mcumgr **looks
+like** a management/security feature and is routinely assumed to provide
+properties it does not.
+
+- **No authentication.** SMP carries no credential. The server does not
+  verify *who* sent a frame. *(inferred — §14 Q1)*
+- **No authorization.** There is no per-command permission model; if a
+  group is compiled in, every command in it is available to every peer
+  that can reach the transport. *(inferred — §14 Q1)*
+- **No confidentiality.** SMP frames are plaintext; any payload secrecy
+  is the transport's (e.g. BLE link encryption). *(inferred — §14 Q1)*
+- **No integrity / no anti-tamper / no replay protection at the SMP
+  layer.** `nh_seq` correlates responses; it is not a nonce. *(documented:
+  "Seq: TBD"; §14 Q12)*
+- **No guarantee that an accepted firmware image is authentic or
+  bootable.** mcumgr writes bytes to a slot; **MCUboot** decides whether
+  the image runs. An "unauthenticated firmware upload" finding against
+  mcumgr is OUT-OF-MODEL — it is intended behaviour with the gate
+  elsewhere (§3.3, §11a). *(documented: README; §14 Q2)*
+- **No DoS resistance.** A peer that can reach the transport can flood,
+  reset (`os_mgmt`), or wedge the device; mcumgr makes no availability
+  guarantee against an on-transport adversary. *(inferred — §14 Q16)*
+- **No constant-time / side-channel guarantees.** *(inferred — §14 Q17)*
+
+### False friends
+
+- **"SMP" / "management protocol" sounds authenticated.** It is not — it
+  is a transport-agnostic RPC with no security layer of its own.
+- **`img_mgmt` "image hash" (`sha`) is an integrity/identification aid,
+  not an authenticity check.** The cryptographic *authenticity* gate is
+  MCUboot's signature verification, separately. *(inferred — §14 Q2)*
+
+## §10 Downstream responsibilities
+
+The integrator — not mcumgr — owns device security. Concretely:
+
+1. **Gate the transport.** Require BLE bonding + LE Secure Connections
+   encryption (configured in nimble); restrict serial to
+   physically-trusted access; firewall/authenticate any UDP transport.
+   An open transport = full device control to anyone who can reach it.
+2. **Compile in only the groups you need.** Disable shell exec
+   (`SHELL_BRIDGE`) and
+   `fs_mgmt` in production unless the product genuinely requires remote
+   shell / file access. Treat them as debug-only.
+3. **Enable secure boot.** Ensure MCUboot (or equivalent) is present and
+   configured to **reject unsigned/untrusted images**, so `img_mgmt`
+   upload cannot become code execution.
+4. **Bound and rate-limit at the transport** if availability matters.
+5. **Assume any reachable, enabled command is fully exercised by an
+   adversary.** Threat-model the *product* on that basis.
+
+## §11 Known misuse patterns
+
+- Exposing `img_mgmt`/`fs_mgmt`/shell exec over an **unencrypted,
+  un-bonded BLE** connection in a shipped product.
+- Shipping with **shell exec (`SHELL_BRIDGE`) enabled** (remote arbitrary 
command
+  execution) because it was handy in development.
+- **Relying on mcumgr for access control** ("only our app speaks SMP") —
+  any peer on the transport can speak SMP.
+- **Assuming firmware upload needs a credential** — it does not; only
+  MCUboot's signature check stands between an uploaded image and boot,
+  and only if enabled.
+- **Disabling MCUboot signature verification** for convenience while
+  leaving `img_mgmt` reachable.
+- Treating the `sha`/hash in image upload as an authenticity guarantee.
+
+## §11a Known non-findings (recurring false positives)
+
+These are the reports a scanner/fuzzer/researcher will most predictably
+file against mcumgr that are **out of model by design**. Triagers should
+close them with the cited section.
+
+| Reported as | Why it is a non-finding | Cite |
+| --- | --- | --- |
+| "SMP endpoint has no authentication / authorization" | By design — 
authn/authz is not an mcumgr property; the integrator gates the transport. | 
§9, §10.1 |
+| "Unauthenticated firmware update / DFU over BLE/serial" | Intended; image 
*execution* is gated by MCUboot signature verification, which is separate. | 
§3.3, §9 |
+| "shell exec (`SHELL_BRIDGE`) allows arbitrary command execution" | Opt-in, 
build-time-gated debug feature for trusted contexts; not compiled in for 
hardened builds. | §5a, §6, §10.2 |
+| "`os_mgmt` taskstat/mpstat leaks internal memory/task layout" | Diagnostic 
by design; same transport-trust assumption as every other command. | §6, §9 |
+| "`os_mgmt` reset lets a peer reboot the device (DoS)" | No availability 
guarantee against an on-transport adversary is claimed. | §9 |
+| "No replay protection — frames can be replayed" | Correct; `nh_seq` is a 
correlator, not a nonce; not claimed. | §9 |
+| "SMP frames are sent in cleartext" | Confidentiality is the transport's job 
(BLE link encryption), not SMP's. | §9, §10.1 |
+| "Image `sha` is not a real signature" | Correct — it is an 
identifier/integrity aid; authenticity is MCUboot's. | §9 false-friends |
+
+Anything resting on **"…but there's no authentication/encryption"** is
+almost certainly this row, not a bug — confirm the report instead
+describes a *memory-safety* or *bounds* failure in the parse/dispatch/
+decode path before treating it as valid (§13).
+
+## §12 Conditions that would change this model
+
+- Adding an authentication or authorization layer to SMP (would create
+  real §8 properties and move several §9 items).
+- A new transport whose default reachability differs (e.g. an always-on
+  IP transport).
+- A new command group, or making a currently-opt-in group (shell, fs)
+  default-on.
+- Moving image-signature verification *into* mcumgr (today it is
+  MCUboot's).
+- A change to where upload buffers live (stack → heap) or how chunk
+  bounds are enforced.
+
+## §13 Triage dispositions
+
+| Disposition | Use when |
+| --- | --- |
+| **VALID** | Memory-unsafety, stack/heap overflow, OOB read/write, or 
unbounded resource use reachable by a crafted SMP frame on a compiled-in 
handler (§6, §8) — i.e. it breaks *even with the transport perfectly secured*. |
+| **OUT-OF-MODEL** | The report depends on the absence of 
authn/authz/encryption/replay protection, or on a malicious-but-well-formed 
command (§9). These are intended; the gate is the transport / bootloader / 
build config. |
+| **DOWNSTREAM** | The fix is the integrator's: enable bonding, disable a 
group, turn on MCUboot signature verification, firewall the transport (§10). |
+| **NON-FINDING** | Matches a §11a row. |
+| **MODEL-GAP** | Real and in spirit in-scope, but no §8 property or §9 
disclaimer covers it yet → feeds a §14 question and a model update. |
+
+## §14 Open questions for the maintainers
+
+Grouped; each promotes an *(inferred)* claim above to *(maintainer)* once
+answered. **Szymon Janc (Mynewt PMC) answered the following on
+2026-07-27**; his answers are folded into the body above and retained
+here.
+
+**Core protocol / trust — ANSWERED**
+- **Q1.** SMP provides no authentication, authorization, confidentiality,
+  integrity or replay protection of its own; all delegated to the
+  transport/integrator. → **Confirmed.**
+- **Q2.** mcumgr stages an image; MCUboot's signature verification is the
+  sole gate on execution. → **Correct.**
+- **Q3.** Single-address-space / no privilege separation — a memory bug in
+  any handler is whole-device. → **Confirmed.**
+
+**Porting / environment — ANSWERED**
+- **Q4.** Which porting-layer guarantees does mcumgr rely on?
+  → **Scope this model to the Mynewt porting layer.** Zephyr forked
+  mcumgr into its own tree and no longer uses this repository. The PMC's
+  long-term plan is to move mcumgr back into `apache/mynewt-core`.
+  (§1, §2, §3.4, §3.5)
+
+**Build-time surface**
+- **Q5.** Which command groups are default-on? → **On Mynewt there is no
+  clear "default".** What is compiled in depends on which packages the
+  application or a system component pulls in, and that is a per-sample
+  configuration choice. The rule of thumb is that a group must be
+  **explicitly enabled by the user** — either directly in the app, or
+  transitively by pulling a package that depends on it (e.g. enabling USB
+  may pull `img_mgmt`). Zephyr's defaults are out of model (see Q4).
+  *(maintainer)*
+- **Q6.** Where is the attacker-supplied chunk length validated relative
+  to the stack copy? → **Handed to `cbor_read_object()` via `cbor_attr_t`**
+  — i.e. the bound is enforced by the cborattr layer rather than by an
+  explicit pre-copy check in the handler. *(maintainer)* The robustness of
+  that path is still worth a scan's attention (§6).
+- **Q7.** Does `fs_mgmt` constrain paths to an intended directory, or is
+  full-filesystem read/write the intended (integrator-gated) behaviour?
+  *(still open)*
+- **Q8.** What do the `img_mgmt` "dummy header" / direct-upload syscfg
+  toggles do? → **They are used in unit tests.** Not a production
+  security surface. *(maintainer)*
+
+**Parse hardening**
+- **Q9.** How are reserved `nh_flags` bits and server-side receipt of
+  `*_RSP` opcodes handled?
+- **Q10.** Is `nh_len` ever used as a copy size before being validated
+  against the actually-received byte count?
+- **Q11.** Behaviour on unknown `(group,id)` — guaranteed clean error?
+- **Q12.** Confirm `nh_seq` carries no security/ordering guarantee.
+- **Q13.** Are `os_mgmt` diagnostics (taskstat/mpstat) intentional
+  information disclosure to any transport peer? → **Yes.** *(maintainer)*
+- **Q14.** Is `shell_mgmt` intended strictly for development? → **Believed
+  so — but it is a Zephyr-only feature**, so for this model (Mynewt
+  porting layer, Q4) it is largely moot. *(maintainer)*
+  *Note (move into core):* on Mynewt the same remote shell execution
+  group is provided by `sys/shell` when `SHELL_BRIDGE` is enabled (it is
+  disabled by default), so the shell exec rows above refer to it.
+- **Q15.** Does mcumgr bound CBOR nesting/size before handing the payload
+  to tinycbor? → **No — that is up to the decoder.** Robustness against
+  hostile CBOR is tinycbor's/cborattr's, which makes that path a
+  first-order target for review (§6). *(maintainer)*
+- **Q16.** Any intended DoS/rate-limit posture? → **It is on the
+  transport.** mcumgr claims none of its own. *(maintainer)*
+- **Q17.** Confirm no constant-time / side-channel guarantees are claimed.
+  → **Confirmed.** *(maintainer)*
+
+**Meta — ANSWERED**
+- **Q18.** OK for this `THREAT_MODEL.md` to become the canonical model,
+  reached via `AGENTS.md → SECURITY.md → THREAT_MODEL.md`? → **Yes** —
+  that chain lands in this same PR.
+- **Q19.** Should the model scope itself to the Apache repo only, or note
+  Zephyr divergences? → **Apache repo only.** Zephyr forked mcumgr and no
+  longer consumes this repository (§3.5). *(maintainer)*
+
+**Still open** — Q7 (`fs_mgmt` path constraint) and the parse-hardening
+questions Q9–Q12 above. Szymon noted some of these touch very low-level
+detail; they are not blocking and the affected claims stay *(inferred)*.
+
+## Appendix: existing security-policy artefacts → §x back-map
+
+At `master @ 0b63bc54308b`, `apache/mynewt-mcumgr` contains **no
+`SECURITY.md`, no `AGENTS.md`, and no prior threat-model document**
+(only `protocol.md` and the per-transport `transport/*.md` notes, which
+are protocol documentation, not security policy). There is therefore
+nothing to back-map or supersede; this is a greenfield v0. The
+`protocol.md` frame/format details are cited inline above as
+*(documented)*.
diff --git a/mgmt/mcumgr/docs/protocol.md b/mgmt/mcumgr/docs/protocol.md
new file mode 100644
index 000000000..ddf8cb6db
--- /dev/null
+++ b/mgmt/mcumgr/docs/protocol.md
@@ -0,0 +1,277 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+
+# SMP (Simple Management Protocol) Protocol Notes
+
+The `mcumgr` SMP server and `mcumgr-cli` SMP client tool 
([source](https://github.com/apache/mynewt-mcumgr-cli))
+use a custom protocol to send commands and responses between the server and 
client using a
+variety of transports (currently TTY serial or BLE).
+
+The protocol isn't fully documented but the following information has been 
inferred
+from the source code available on Github and using the `-l DEBUG` flag when
+executing commands.
+
+## Source Code
+
+**SMP** is based on the earlier **NMP**, which is part of [Apache 
Mynewt](https://mynewt.apache.org/).
+
+The golang source for the original **newtmgr** is [available 
here](https://github.com/apache/mynewt-newtmgr),
+and can be used to provide some insight into how data is exchanged between the
+utility and the device under test.
+
+Apache Mynewt core (`mgmt/mcumgr`) implements an SMP server in **C**,
+and a new command-line SMP client called **mcumgr** was created at
+[apache/mynewt-mcumgr-cli](https://github.com/apache/mynewt-mcumgr-cli).
+
+## SMP Frame Format
+
+### Endianness
+
+Frames are normally serialized as **Big Endian** when dealing with values > 8 
bits. This is
+mandatory in NMP, but the SMP implementation does add support for **Little 
Endian** as an
+option at the struct level, as shown below.
+
+### Frame Header
+
+Frames in SMP have the following header format:
+
+```
+struct mgmt_hdr {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+    uint8_t  nh_op:3;           /* MGMT_OP_[...] */
+    uint8_t  _res1:5;
+#endif
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+    uint8_t  _res1:5;
+    uint8_t  nh_op:3;           /* MGMT_OP_[...] */
+#endif
+    uint8_t  nh_flags;          /* Reserved for future flags */
+    uint16_t nh_len;            /* Length of the payload */
+    uint16_t nh_group;          /* MGMT_GROUP_ID_[...] */
+    uint8_t  nh_seq;            /* Sequence number */
+    uint8_t  nh_id;             /* Message ID within group */
+};
+```
+
+The NMP/newtmgr [go 
source](https://github.com/apache/mynewt-newtmgr/blob/master/nmxact/nmp/nmp.go) 
is as follows,
+without the option to select endianness:
+
+```
+type NmpHdr struct {
+       Op    uint8 /* 3 bits of opcode */
+       Flags uint8
+       Len   uint16
+       Group uint16
+       Seq   uint8
+       Id    uint8
+}
+```
+
+`nh_op` (or `Op` in newtmgr) can be one of the following values:
+
+```
+/** Opcodes; encoded in first byte of header. */
+#define MGMT_OP_READ            0
+#define MGMT_OP_READ_RSP        1
+#define MGMT_OP_WRITE           2
+#define MGMT_OP_WRITE_RSP       3
+```
+
+- **`op`**: The operation code
+- **`Flags`**: TBD
+- **`Len`**:  The payload len when `Data` is present
+- **`Group`**: Commands are organized into groups. Groups are defined
+  [here](../mgmt/include/mgmt/mgmt.h).
+- **`Seq`**: TBD
+- **`Id`**: The command ID to send. Commands in the default `Group` are defined
+  [here](../mgmt/include/mgmt/mgmt.h).
+
+SMP header (Little Endian)
+
+```
+ 0                   1                   2                   3  
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|  OP |   Res.  |      Flags    |             Length            |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|            Group ID           |    Sequence   |   Command ID  |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+```
+
+#### `Data` Payload
+
+If `nh_len` (`Len` in nmp) is non-zero, the `nh_len` byte payload (referred to 
as **`Data`** in this document) immediately follows the frame header.
+
+### Example Packets
+
+The following example commands show how the different fields work:
+
+#### Simple Read Request: `taskstats`
+
+The following example corresponds to the `taskstats` command 
([source](../cmd/os_mgmt/include/os_mgmt/os_mgmt.h)), and
+can be seen by running `mcumgr -l DEBUG -c serial taskstats`:
+
+```
+Op:    0  # NMGR_OP_READ
+Flags: 0
+Len:   0  # No payload present
+Group: 0  # 0x00 = NMGR_GROUP_ID_DEFAULT
+Seq:   0
+Id:    2  # 0x02 in group 0x00 = OS_MGMT_ID_TASKSTAT
+Data:  [] # No payload (len = 0 above)
+```
+
+When serialized this will be sent as `0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x02`.
+
+If this was sent using the serial port, you would get the following request 
and response:
+
+```
+$ mcumgr -l DEBUG -c serial taskstats
+2016/11/11 12:45:44 [DEBUG] Writing newtmgr request &{Op:0 Flags:0 Len:0 
Group:0 Seq:0 Id:2 Data:[]}
+2016/11/11 12:45:44 [DEBUG] Serializing request &{Op:0 Flags:0 Len:0 Group:0 
Seq:0 Id:2 Data:[]} into buffer [0 0 0 0 0 0 0 2]
+2016/11/11 12:45:44 [DEBUG] Tx packet dump:
+00000000  00 00 00 00 00 00 00 02                           |........|
+
+2016/11/11 12:45:44 [DEBUG] Writing [6 9] to data channel
+2016/11/11 12:45:44 [DEBUG] Writing [65 65 111 65 65 65 65 65 65 65 65 65 65 
105 66 67] to data channel
+2016/11/11 12:45:44 [DEBUG] Writing [10] to data channel
+2016/11/11 12:45:44 [DEBUG] Reading [6 9 65 65 111 65 65 65 65 65 65 65 65 65 
65 105 66 67] from data channel
+2016/11/11 12:45:44 [DEBUG] Rx packet dump:
+00000000  00 00 00 00 00 00 00 02                           |........|
+
+2016/11/11 12:45:44 [DEBUG] Deserialized response &{Op:0 Flags:0 Len:0 Group:0 
Seq:0 Id:2 Data:[]}
+2016/11/11 12:45:44 [DEBUG] Reading [13] from data channel
+2016/11/11 12:45:44 [DEBUG] Reading [6 9 65 90 119 66 65 81 71 83 65 65 65 65 
65 114 57 105 99 109 77 65 90 88 82 104 99 50 116 122 118 50 82 112 90 71 120 
108 118 50 82 119 99 109 108 118 71 80 57 106 100 71 108 107 65 71 86 122 100 
71 70 48 90 81 70 109 99 51 82 114 100 88 78 108 71 66 108 109 99 51 82 114 99 
50 108 54 71 69 66 109 89 51 78 51 89 50 53 48 71 103 65 85 102 109 112 110 99 
110 86 117 100 71 108 116 90 82 111 65 69 53 120 80 98 71 120 104 99 51 82 102] 
from data channel
+2016/11/11 12:45:44 [DEBUG] Reading [4 20 89 50 104 108 89 50 116 112 98 103 
66 115 98 109 86 52 100 70 57 106 97 71 86 106 97 50 108 117 65 80 57 109 89 
109 120 108 88 50 120 115 118 50 82 119 99 109 108 118 65 71 78 48 97 87 81 66 
90 88 78 48 89 88 82 108 65 109 90 122 100 71 116 49 99 50 85 89 79 109 90 122 
100 71 116 122 97 88 111 89 85 71 90 106 99 51 100 106 98 110 81 90 54 112 120 
110 99 110 86 117 100 71 108 116 90 82 107 74 82 87 120 115 89 88 78 48 88 50 
78 111] from data channel
+2016/11/11 12:45:44 [DEBUG] Reading [4 20 90 87 78 114 97 87 52 65 98 71 53 
108 101 72 82 102 89 50 104 108 89 50 116 112 98 103 68 47 98 109 74 115 90 88 
86 104 99 110 82 102 89 110 74 112 90 71 100 108 118 50 82 119 99 109 108 118 
66 87 78 48 97 87 81 67 90 88 78 48 89 88 82 108 65 87 90 122 100 71 116 49 99 
50 85 89 72 50 90 122 100 71 116 122 97 88 111 90 65 81 66 109 89 51 78 51 89 
50 53 48 71 103 65 84 113 89 78 110 99 110 86 117 100 71 108 116 90 81 66 115] 
from data channel
+2016/11/11 12:45:44 [DEBUG] Reading [4 20 98 71 70 122 100 70 57 106 97 71 86 
106 97 50 108 117 65 71 120 117 90 88 104 48 88 50 78 111 90 87 78 114 97 87 52 
65 47 50 100 105 98 71 86 119 99 110 66 111 118 50 82 119 99 109 108 118 65 87 
78 48 97 87 81 68 90 88 78 48 89 88 82 108 65 87 90 122 100 71 116 49 99 50 85 
89 48 50 90 122 100 71 116 122 97 88 111 90 65 86 66 109 89 51 78 51 89 50 53 
48 71 81 113 68 90 51 74 49 98 110 82 112 98 87 85 69 98 71 120 104] from data 
channel
+2016/11/11 12:45:44 [DEBUG] Reading [4 20 99 51 82 102 89 50 104 108 89 50 116 
112 98 103 66 115 98 109 86 52 100 70 57 106 97 71 86 106 97 50 108 117 65 80 
47 47 47 56 85 88] from data channel
+2016/11/11 12:45:44 [DEBUG] Rx packet dump:
+00000000  01 01 01 92 00 00 00 02  bf 62 72 63 00 65 74 61  |.........brc.eta|
+00000010  73 6b 73 bf 64 69 64 6c  65 bf 64 70 72 69 6f 18  |sks.didle.dprio.|
+00000020  ff 63 74 69 64 00 65 73  74 61 74 65 01 66 73 74  |.ctid.estate.fst|
+00000030  6b 75 73 65 18 19 66 73  74 6b 73 69 7a 18 40 66  |kuse..fstksiz.@f|
+00000040  63 73 77 63 6e 74 1a 00  14 7e 6a 67 72 75 6e 74  |cswcnt...~jgrunt|
+00000050  69 6d 65 1a 00 13 9c 4f  6c 6c 61 73 74 5f 63 68  |ime....Ollast_ch|
+00000060  65 63 6b 69 6e 00 6c 6e  65 78 74 5f 63 68 65 63  |eckin.lnext_chec|
+00000070  6b 69 6e 00 ff 66 62 6c  65 5f 6c 6c bf 64 70 72  |kin..fble_ll.dpr|
+00000080  69 6f 00 63 74 69 64 01  65 73 74 61 74 65 02 66  |io.ctid.estate.f|
+00000090  73 74 6b 75 73 65 18 3a  66 73 74 6b 73 69 7a 18  |stkuse.:fstksiz.|
+000000a0  50 66 63 73 77 63 6e 74  19 ea 9c 67 72 75 6e 74  |Pfcswcnt...grunt|
+000000b0  69 6d 65 19 09 45 6c 6c  61 73 74 5f 63 68 65 63  |ime..Ellast_chec|
+000000c0  6b 69 6e 00 6c 6e 65 78  74 5f 63 68 65 63 6b 69  |kin.lnext_checki|
+000000d0  6e 00 ff 6e 62 6c 65 75  61 72 74 5f 62 72 69 64  |n..nbleuart_brid|
+000000e0  67 65 bf 64 70 72 69 6f  05 63 74 69 64 02 65 73  |ge.dprio.ctid.es|
+000000f0  74 61 74 65 01 66 73 74  6b 75 73 65 18 1f 66 73  |tate.fstkuse..fs|
+00000100  74 6b 73 69 7a 19 01 00  66 63 73 77 63 6e 74 1a  |tksiz...fcswcnt.|
+00000110  00 13 a9 83 67 72 75 6e  74 69 6d 65 00 6c 6c 61  |....gruntime.lla|
+00000120  73 74 5f 63 68 65 63 6b  69 6e 00 6c 6e 65 78 74  |st_checkin.lnext|
+00000130  5f 63 68 65 63 6b 69 6e  00 ff 67 62 6c 65 70 72  |_checkin..gblepr|
+00000140  70 68 bf 64 70 72 69 6f  01 63 74 69 64 03 65 73  |ph.dprio.ctid.es|
+00000150  74 61 74 65 01 66 73 74  6b 75 73 65 18 d3 66 73  |tate.fstkuse..fs|
+00000160  74 6b 73 69 7a 19 01 50  66 63 73 77 63 6e 74 19  |tksiz..Pfcswcnt.|
+00000170  0a 83 67 72 75 6e 74 69  6d 65 04 6c 6c 61 73 74  |..gruntime.llast|
+00000180  5f 63 68 65 63 6b 69 6e  00 6c 6e 65 78 74 5f 63  |_checkin.lnext_c|
+00000190  68 65 63 6b 69 6e 00 ff  ff ff                    |heckin....|
+
+2016/11/11 12:45:44 [DEBUG] Deserialized response &{Op:1 Flags:1 Len:402 
Group:0 Seq:0 Id:2 Data:[191 98 114 99 0 101 116 97 115 107 115 191 100 105 100 
108 101 191 100 112 114 105 111 24 255 99 116 105 100 0 101 115 116 97 116 101 
1 102 115 116 107 117 115 101 24 25 102 115 116 107 115 105 122 24 64 102 99 
115 119 99 110 116 26 0 20 126 106 103 114 117 110 116 105 109 101 26 0 19 156 
79 108 108 97 115 116 95 99 104 101 99 107 105 110 0 108 110 101 120 116 95 99 
104 101 99 107 105 110 0  [...]
+Return Code = 0
+      task pri tid  runtime      csw    stksz   stkuse last_checkin 
next_checkin
+  bleuart_bridge   5   2        0  1288579      256       31        0        0
+   bleprph   1   3        4     2691      336      211        0        0
+      idle 255   0  1285199  1343082       64       25        0        0
+    ble_ll   0   1     2373    60060       80       58        0        0
+```
+
+#### Group Read Request: `image list`
+
+The following command lists images on the device and uses commands from `Group`
+0x01 (`MGMT_GROUP_ID_IMAGE`), and was generated with `$ mcumgr -l DEBUG -c 
serial image list`:
+
+> See [img_mgmt](../cmd/img_mgmt)
+for a full list of commands in the IMAGE `Group`.
+
+```
+$ mcumgr -l DEBUG -c serial image list
+2016/11/11 12:25:51 [DEBUG] Writing newtmgr request &{Op:0 Flags:0 Len:0 
Group:1 Seq:0 Id:0 Data:[]}
+2016/11/11 12:25:51 [DEBUG] Serializing request &{Op:0 Flags:0 Len:0 Group:1 
Seq:0 Id:0 Data:[]} into buffer [0 0 0 0 0 1 0 0]
+2016/11/11 12:25:51 [DEBUG] Tx packet dump:
+00000000  00 00 00 00 00 01 00 00                           |........|
+
+2016/11/11 12:25:51 [DEBUG] Writing [6 9] to data channel
+2016/11/11 12:25:51 [DEBUG] Writing [65 65 111 65 65 65 65 65 65 65 69 65 65 
68 99 119] to data channel
+2016/11/11 12:25:51 [DEBUG] Writing [10] to data channel
+2016/11/11 12:25:51 [DEBUG] Reading [6 9 65 65 111 65 65 65 65 65 65 65 69 65 
65 68 99 119] from data channel
+2016/11/11 12:25:51 [DEBUG] Rx packet dump:
+00000000  00 00 00 00 00 01 00 00                           |........|
+
+2016/11/11 12:25:51 [DEBUG] Deserialized response &{Op:0 Flags:0 Len:0 Group:1 
Seq:0 Id:0 Data:[]}
+2016/11/11 12:25:51 [DEBUG] Reading [13] from data channel
+2016/11/11 12:25:51 [DEBUG] Reading [6 9 65 73 85 66 65 81 66 55 65 65 69 65 
65 76 57 109 97 87 49 104 90 50 86 122 110 55 57 107 99 50 120 118 100 65 66 
110 100 109 86 121 99 50 108 118 98 109 85 119 76 106 77 117 77 71 82 111 89 88 
78 111 87 67 68 83 84 76 77 70 69 49 81 88 75 55 85 81 110 53 121 48 114 110 
104 104 50 87 49 113 47 102 120 71 50 48 103 115 54 121 48 48 113 75 101 79 48 
71 104 105 98 50 57 48 89 87 74 115 90 102 86 110 99 71 86 117 90 71 108 117] 
from data channel
+2016/11/11 12:25:51 [DEBUG] Reading [4 20 90 47 82 112 89 50 57 117 90 109 108 
121 98 87 86 107 57 87 90 104 89 51 82 112 100 109 88 49 47 47 57 114 99 51 66 
115 97 88 82 84 100 71 70 48 100 88 77 65 47 49 78 116] from data channel
+2016/11/11 12:25:51 [DEBUG] Rx packet dump:
+00000000  01 01 00 7b 00 01 00 00  bf 66 69 6d 61 67 65 73  |...{.....fimages|
+00000010  9f bf 64 73 6c 6f 74 00  67 76 65 72 73 69 6f 6e  |..dslot.gversion|
+00000020  65 30 2e 33 2e 30 64 68  61 73 68 58 20 d2 4c b3  |e0.3.0dhashX .L.|
+00000030  05 13 54 17 2b b5 10 9f  9c b4 ae 78 61 d9 6d 6a  |..T.+......xa.mj|
+00000040  fd fc 46 db 48 2c eb 2d  34 a8 a7 8e d0 68 62 6f  |..F.H,.-4....hbo|
+00000050  6f 74 61 62 6c 65 f5 67  70 65 6e 64 69 6e 67 f4  |otable.gpending.|
+00000060  69 63 6f 6e 66 69 72 6d  65 64 f5 66 61 63 74 69  |iconfirmed.facti|
+00000070  76 65 f5 ff ff 6b 73 70  6c 69 74 53 74 61 74 75  |ve...ksplitStatu|
+00000080  73 00 ff                                          |s..|
+
+2016/11/11 12:25:51 [DEBUG] Deserialized response &{Op:1 Flags:1 Len:123 
Group:1 Seq:0 Id:0 Data:[191 102 105 109 97 103 101 115 159 191 100 115 108 111 
116 0 103 118 101 114 115 105 111 110 101 48 46 51 46 48 100 104 97 115 104 88 
32 210 76 179 5 19 84 23 43 181 16 159 156 180 174 120 97 217 109 106 253 252 
70 219 72 44 235 45 52 168 167 142 208 104 98 111 111 116 97 98 108 101 245 103 
112 101 110 100 105 110 103 244 105 99 111 110 102 105 114 109 101 100 245 102 
97 99 116 105 118 101 2 [...]
+Images:
+ slot=0
+    version: 0.3.0
+    bootable: true
+    flags: active confirmed
+    hash: d24cb3051354172bb5109f9cb4ae7861d96d6afdfc46db482ceb2d34a8a78ed0
+Split status: N/A
+```
+
+When serialised this will be sent as `0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x00`.
+
+## Transports
+
+### Mcumgr/Newtmgr SMP Client Over Serial
+
+`mcumgr` or `newtmgr` can be used over TTY serial with the following parameters
+to connect to a SMP server running on the target device:
+
+- Baud Rate: 115200
+- HW Flow Control: None
+
+### Mcumgr/Newtmgr SMP Client Over BLE
+
+`mcumgr` or `newtmgr` can be used over BLE with the following GATT service and
+characteristic UUIDs to connect to a SMP server running on the target device:
+
+- **Service UUID**: `8D53DC1D-1DB7-4CD3-868B-8A527460AA84`
+- **Characteristic UUID**: `DA2E7828-FBCE-4E01-AE9E-261174997C48`
+
+The  "SMP" GATT service consists of one **write no-rsp characteristic**
+for SMP requests: a single-byte characteristic that
+can only accepts write-without-response commands. The contents of
+each write command contains an SMP request.
+
+SMP responses are sent back in the form of unsolicited notifications
+from the same characteristic.
diff --git a/mgmt/mcumgr/docs/smp-bluetooth.md 
b/mgmt/mcumgr/docs/smp-bluetooth.md
new file mode 100644
index 000000000..d2e06fb45
--- /dev/null
+++ b/mgmt/mcumgr/docs/smp-bluetooth.md
@@ -0,0 +1,71 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+
+# SMP over Bluetooth
+
+This document specifies how the mcumgr Simple Management Procotol (SMP) is
+transmitted over Bluetooth.
+
+## Overview
+
+All SMP communication utilizes a single GATT characteristic.  An SMP request is
+sent in the form of either 1) a GATT Write Command, or 2) a GATT Write Without
+Response command.  An SMP response is sent in the form of a GATT Notification
+specifying the same characteristic that was written.
+
+If an SMP request or response is too large to fit in a single GATT command, the
+sender fragments it across several commands.  No additional framing is
+introduced when a request or response is fragmented; the payload is simply
+split among several commands.  Since Bluetooth guarantees ordered delivery of
+packets, the SMP header in the first fragment contains sufficient information
+for reassembly.
+
+## Services
+
+### SMP service
+
+UUID: `8D53DC1D-1DB7-4CD3-868B-8A527460AA84`
+
+### Characteristics
+
+#### SMP Characteristic
+
+| Field | Value                                                             |
+| ----- | ----------------------------------------------------------------- |
+| Name                  | SMP                                               |
+| Description           | Used for both SMP requests and responses.         |
+| Read                  | Excluded                                          |
+| Write                 | Mandatory                                         |
+| WriteWithoutResponse  | Mandatory                                         |
+| SignedWrite           | Excluded                                          |
+| Notify                | Mandatory                                         |
+| Indicate              | Excluded                                          |
+| WritableAuxiliaries   | Excluded                                          |
+| Broadcast             | Excluded                                          |
+| ExtendedProperties    |                                                   |
+
+As indicated, SMP requests can be sent in the form of either a Write or a Write
+Without Response.  The Write Without Response form is generally preferred, as
+an application-layer response is always sent in the form of a Notification.
+The regular Write form is accepted in case the client requires a GATT response
+to initiate pairing.
+
+Security for this characteristic is optional.
diff --git a/mgmt/mcumgr/docs/smp-console.md b/mgmt/mcumgr/docs/smp-console.md
new file mode 100644
index 000000000..5f80bf7ca
--- /dev/null
+++ b/mgmt/mcumgr/docs/smp-console.md
@@ -0,0 +1,78 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+
+# SMP over console
+
+This document specifies how the mcumgr Simple Management Procotol (SMP) is
+transmitted over text consoles.
+
+## Overview
+
+Mcumgr packets sent over serial are fragmented into frames of 127 bytes or
+fewer.  This 127-byte maximum applies to the entire frame, including header,
+CRC, and terminating newline.
+
+The initial frame in a packet has the following format:
+
+```
+    offset 0:    0x06 0x09
+    === Begin base64 encoding ===
+    offset 2:    <16-bit packet-length>
+    offset ?:    <body>
+    offset ?:    <crc16> (if final frame)
+    === End base64 encoding ===
+    offset ?:    0x0a (newline)
+```
+
+All subsequent frames have the following format:
+
+```
+    offset 0:    0x04 0x14
+    === Begin base64 encoding ===
+    offset 2:    <body>
+    offset ?:    <crc16> (if final frame)
+    === End base64 encoding ===
+    offset ?:    0x0a (newline)
+```
+
+All integers are represented in big-endian.  The packet fields are described
+below:
+
+| Field | Description |
+| ----- | ----------- |
+| 0x06 0x09 | Byte pair indicating the start of a packet. |
+| 0x04 0x14 | Byte pair indicating the start of a continuation frame. |
+| Packet length | The combined total length of the *unencoded* body plus the 
final CRC (2 bytes). Length is in Big-Endian format. |
+| Body | The actual SMP data (i.e., 8-byte header and CBOR key-value map). |
+| CRC16 | A CRC16 of the *unencoded* body of the entire packet.  This field is 
only present in the final frame of a packet. |
+| Newline | A 0x0a byte; terminates a frame. |
+
+The packet is fully received when <packet-length> bytes of body has been
+received.
+
+## CRC details
+
+The CRC16 should be calculated with the following parameters:
+
+| Field         | Value         |
+| ------------- | ------------- |
+| Polynomial    | 0x1021        |
+| Initial Value | 0             |

Reply via email to