blob: ffbac3bf78331a7c4fa719e63a08569d1d68c4bc [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file describes the format of delivery blobs as specified in RFC 0207.
// It includes high-level types for interfacing with a delivery blob.
#ifndef SRC_STORAGE_BLOBFS_DELIVERY_BLOB_H_
#define SRC_STORAGE_BLOBFS_DELIVERY_BLOB_H_
#include <lib/stdcompat/span.h>
#include <lib/zx/result.h>
#include <zircon/compiler.h>
#include <cstdint>
#include <cstdlib>
#include <optional>
#include <string_view>
#include <vector>
#include <fbl/array.h>
#include "src/lib/digest/digest.h"
namespace blobfs {
constexpr std::string_view kDeliveryBlobPrefix = "v1-";
// Type of the delivery blob's metadata/payload. Corresponds to the `--type` argument used to
// generate the blob with the `blobfs-compression` tool.
//
// *WARNING*: The underlying values of these fields form are used in external tools when generating
// delivery blobs as per RFC 0207. Use caution when changing or re-using the values specified here.
enum class DeliveryBlobType : uint32_t {
// Reserved for future use.
kReserved = 0,
// Type-1 blobs support the zstd-chunked compression format or are uncompressed.
kType1 = 1,
};
// Header of a delivery blob as specified in RFC 0207.
struct DeliveryBlobHeader {
// Header Fields:
// 32-bit magic number.
uint8_t magic[4];
// Type of blob the metadata/payload represent.
DeliveryBlobType type;
// Total header length, including metadata associated with `type`. For a given delivery blob,
// the metadata starts after `sizeof(DeliveryBlobHeader)` bytes, and the payload section starts
// after `header_length` bytes.
uint32_t header_length;
// Methods:
// Check if the header is valid (i.e. `magic` is correct, `type` is a valid value).
bool IsValid() const;
// Create a new `DeliveryBlobHeader` with the specified `metadata_length`.
static DeliveryBlobHeader Create(DeliveryBlobType type, size_t metadata_length);
// Parse and return a `DeliveryBlobHeader` from a byte `buffer`.
static zx::result<DeliveryBlobHeader> FromBuffer(cpp20::span<const uint8_t> buffer);
};
// Helper function to prepend the final component of `path` with the prefix specified in RFC 0207.
std::string GetDeliveryBlobPath(const std::string_view& path);
// Generate a Type 1 delivery blob payload from the given blob `data` using the default Blobfs
// compression parameters.
//
// If `compress` is not specified, the result will be uncompressed if the compressed data is larger
// than the input. If `compress` is true, the result will always be compressed, and if false, will
// always be uncompressed.
//
// *WARNING*: Modifying the compression parameters used by this function can cause a mismatch
// between the calculated on-disk size used for size checking. This function is used to calculate
// `compressed_file_size` in the blob info JSON file.
zx::result<fbl::Array<uint8_t>> GenerateDeliveryBlobType1(cpp20::span<const uint8_t> data,
std::optional<bool> compress);
// Calculate the Merkle root of an RFC 0207 compliant delivery blob. `data` must be a complete
// delivery blob and cannot include any trailing data.
//
// *WARNING*: Aside from checksum verification and basic validity checks provided by the
// chunked_compression library, this function makes no security guarantees. Decompression is
// performed in the thread/address space of the caller.
zx::result<digest::Digest> CalculateDeliveryBlobDigest(cpp20::span<const uint8_t> data);
} // namespace blobfs
#endif // SRC_STORAGE_BLOBFS_DELIVERY_BLOB_H_