From 67cf7a7daa452673db2b3be523fd19fb68fa223f Mon Sep 17 00:00:00 2001 From: HeHa112 <113408507+HeHa112@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:02:54 +0200 Subject: [PATCH 01/12] In between PR for folder structure (#1) * Added component template for IAV_Primula * Add "Hello World" * test fix * renamed lib to main * Changed documentation part from template to IAV_Primula * Add gitattributes for LF in iav_primula Rust files * Enforce LF for iav_primula BUILD file to satisfy buildifier * Format iav_primula test BUILD for buildifier * copyright header changed * Update BUILD in tests --------- Co-authored-by: cpelka --- .gitattributes | 3 + score/iav_primula/BUILD | 22 ++ .../architecture/chklst_arc_inspection.rst | 204 ++++++++++++++++++ .../architecture/component_architecture.rst | 122 +++++++++++ score/iav_primula/docs/architecture/index.rst | 23 ++ .../docs/component_classification.rst | 188 ++++++++++++++++ .../chklst_impl_inspection.rst | 117 ++++++++++ .../detailed_design/dd_example_ex_dyn.puml | 37 ++++ .../detailed_design/dd_example_ex_sta.puml | 37 ++++ .../detailed_design_example.rst | 87 ++++++++ .../docs/detailed_design/index.rst | 42 ++++ score/iav_primula/docs/index.rst | 201 +++++++++++++++++ score/iav_primula/docs/manuals/.gitkeep | 0 .../requirements/chklst_req_inspection.rst | 178 +++++++++++++++ score/iav_primula/docs/requirements/index.rst | 21 ++ .../docs/requirements/requirements.rst | 76 +++++++ .../aou_requirements_template.rst | 42 ++++ .../iav_primula/docs/safety_analysis/dfa.rst | 36 ++++ .../iav_primula/docs/safety_analysis/fmea.rst | 108 ++++++++++ .../docs/security_analysis/.gitkeep | 0 score/iav_primula/src/details/.gitkeep | 0 score/iav_primula/src/main.rs | 16 ++ score/iav_primula/tests/.gitkeep | 0 score/iav_primula/tests/BUILD | 21 ++ score/iav_primula/tests/hello_test.rs | 19 ++ .../tests/integration_tests/.gitkeep | 0 tests/iav_primula/BUILD | 17 ++ 27 files changed, 1617 insertions(+) create mode 100644 .gitattributes create mode 100644 score/iav_primula/BUILD create mode 100644 score/iav_primula/docs/architecture/chklst_arc_inspection.rst create mode 100644 score/iav_primula/docs/architecture/component_architecture.rst create mode 100644 score/iav_primula/docs/architecture/index.rst create mode 100644 score/iav_primula/docs/component_classification.rst create mode 100644 score/iav_primula/docs/detailed_design/chklst_impl_inspection.rst create mode 100644 score/iav_primula/docs/detailed_design/dd_example_ex_dyn.puml create mode 100644 score/iav_primula/docs/detailed_design/dd_example_ex_sta.puml create mode 100644 score/iav_primula/docs/detailed_design/detailed_design_example.rst create mode 100644 score/iav_primula/docs/detailed_design/index.rst create mode 100644 score/iav_primula/docs/index.rst create mode 100644 score/iav_primula/docs/manuals/.gitkeep create mode 100644 score/iav_primula/docs/requirements/chklst_req_inspection.rst create mode 100644 score/iav_primula/docs/requirements/index.rst create mode 100644 score/iav_primula/docs/requirements/requirements.rst create mode 100644 score/iav_primula/docs/safety_analysis/aou_requirements_template.rst create mode 100644 score/iav_primula/docs/safety_analysis/dfa.rst create mode 100644 score/iav_primula/docs/safety_analysis/fmea.rst create mode 100644 score/iav_primula/docs/security_analysis/.gitkeep create mode 100644 score/iav_primula/src/details/.gitkeep create mode 100644 score/iav_primula/src/main.rs create mode 100644 score/iav_primula/tests/.gitkeep create mode 100644 score/iav_primula/tests/BUILD create mode 100644 score/iav_primula/tests/hello_test.rs create mode 100644 score/iav_primula/tests/integration_tests/.gitkeep create mode 100644 tests/iav_primula/BUILD diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..8d935b038 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +score/iav_primula/src/*.rs text eol=lf +score/iav_primula/tests/*.rs text eol=lf +score/iav_primula/tests/BUILD text eol=lf diff --git a/score/iav_primula/BUILD b/score/iav_primula/BUILD new file mode 100644 index 000000000..c7c2aad84 --- /dev/null +++ b/score/iav_primula/BUILD @@ -0,0 +1,22 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@rules_rust//rust:defs.bzl", "rust_library") + +rust_library( + name = "iav_primula", + srcs = ["src/main.rs"], + crate_name = "iav_primula", + edition = "2021", + visibility = ["//visibility:public"], +) diff --git a/score/iav_primula/docs/architecture/chklst_arc_inspection.rst b/score/iav_primula/docs/architecture/chklst_arc_inspection.rst new file mode 100644 index 000000000..10562ba69 --- /dev/null +++ b/score/iav_primula/docs/architecture/chklst_arc_inspection.rst @@ -0,0 +1,204 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + + +.. document:: IAV Primula Architecture Inspection Checklist + :id: doc__iav_primula_arc_inspection + :status: draft + :safety: QM + :security: NO + :realizes: wp__sw_arch_verification + :tags: iav_primula + +Architecture Inspection Checklist +================================= + +Purpose +------- + +The purpose of the software architecture checklist is to ensure that the design meets the criteria and quality as +defined per project processes and guidelines for feature and component architectural design elements. +It helps to check the compliance with requirements, identify errors or inconsistencies, and ensure adherence to best +practices. +The checklist guides evaluation of the architecture design, identifies potential problems, and aids in +communication and documentation of architectural decisions to stakeholders. + +Conduct +------- + +As described in the concept :need:`doc_concept__wp_inspections` the following "inspection roles" are expected to be filled: + +- content responsible (author): +- reviewer: +- moderator: + +Current state: formal architecture inspection not executed yet. + +Checklist +--------- + +It is mandatory to fill in the "passed" column with "yes" or "no" for each checklist item and additionally to add in the remarks why it is passed or not passed. +In case of "no" an issue link to the issue tracking system has to be added in the last column (if not solved in the same issue). +See also :need:`doc_concept__wp_inspections` for further information about reviews in general and inspection in particular. + +.. list-table:: Architecture Design Review Checklist + :header-rows: 1 + + * - Review Id + - Acceptance criteria + - Guidance + - passed + - Remarks + - Issue link + * - ARC_01_01 + - Is the traceability from software architectural elements to requirements, and other level architectural elements (e.g. component to interface) established according to the "Relations between the architectural elements" as described in :need:`doc_concept__arch_process`? + - automated + - Trace should be checked automatically by tool support in the future. Will be removed from the checklist once the requirement (:need:`Correlations of the architectural building blocks `) is implemented. Refer to `Tool Requirements `_ for the current status. + - + - + * - ARC_01_02 + - Does the software architecture design consider all the requirements allocated or belonging to the architectural element, including functional, non-functional, safety, and security requirements and all related design decisions? + - manual + - Check if all requirements allocated or belonging to the architectural element are considered in the design. This includes functional requirements (e.g. functional safety requirements), non-functional requirements (e.g. performance, reliability), and security requirements (e.g. confidentiality, integrity). Additionally, ensure that all related design decisions are taken into account and documented in the architectural design. + - + - + * - ARC_01_03 + - If the architectural element is related to any supplier manuals (incl. safety and security) + are the relevant parts covered? + - If the architecture makes use of supplied elements, their manuals (like safety) have to be considered (i.e. its provided functionality matches the expectation and assumptions are fulfilled). Note that in case of safety component this means that assumed Technical Safety Requirements and AoUs of the safety manual are covered. + - + - + - + * - ARC_01_04 + - Is the architectural element traceable to the lower level artifacts as defined by the workproduct traceability? + - Will be removed from checklist once the requirement (:need:`Correlations of the architectural building blocks `) is implemented by automated tool check. See `Tool Requirements `_. + Details of possible linking can be depicted from the traceability concept. + - + - + - + * - ARC_02_01 + - Is the software architecture design compliant with the (overall) feature architecture? + - On component level check against the feature architecture, on feature level check other features with common components used. + - + - + - + * - ARC_02_02 + - Is appropriate and comprehensible operation/interface naming present in the architectural design? + - Check :need:`gd_guidl__arch_design` + - + - + - + * - ARC_02_03 + - Are correctness of data flow and control flow within the architectural elements considered? + - E.g. examine definitions, transformations, integrity, and interaction of data; check error handling, data + exchange between elements, correct response to inputs and documented decision making. + Note: consistency is ensured by the process/tooling, by defining each interface only once. + - + - + - + * - ARC_02_04 + - Are the interfaces between the software architectural element and other architectural elements well-defined? + - Check if the interface reacts on non-defined behaviour or errors; can established protocols be used; are the + interfaces for inputs, outputs, error codes documented; is loose coupling considered and only limited exposure; + can unit or integration test be written against the interface; data amount transferred; no sensitive data + exposure; + - + - + - + * - ARC_02_05 + - Does the software architectural element consider the timing constraints (from the parent requirement)? + - If there are hard requirements on the timing a programming time estimation should be performed and also + deadline supervision considered. + - + - + - + * - ARC_02_06 + - Is the documentation of the software architectural element, including textual and graphical descriptions + (e.g., UML diagrams), comprehensible and complete? + - Use of semi-formal notation is expected for architectural elements with an allocated ASIL level. + Is the architecture template correctly filled? + - + - + - + * - ARC_03_01 + - Is the architectural element modular and encapsulated? + - Check e.g. that only minimal interfaces are used. Design should be object oriented. Interfaces and interactions are clearly defined. Usage of access types (private, protected) properly set. Limited global variables. + - + - + - + * - ARC_03_02 + - Is the suitability of the software architecture for future modifications and maintainability considered? + - Check for e.g. loose coupling, separation of concerns, high cohesion, versioning strategy for interfaces, + decision records, use of established design patterns. + - + - + - + * - ARC_03_03 + - Are simplicity and avoidance of unnecessary complexity present in the software architecture and the component? + - Indicators for complexity are: number of use cases (corresponding to dynamic diagrams) + allocated to single design element, number of interfaces and operations in an interface, + function parameters, global variables, complex types, limited comprehensibility. + The belonging code metrics should be checked. + + Notes: + + If the "number of use cases" or "number of interfaces" above exceeds "3" or "number of function parameters" exceeds "5" or the "number of operations" exceeds "20" or global variables are used, a design rationale is mandatory. + + See also if component classification :need:`gd_temp__component_classification` as measure is present. + + - + - + - + * - ARC_03_04 + - Is the software architecture design following best practices and design principles? + - Refer to architectural guidelines and recommendations within the project documentation. + - + - + - + * - ARC_04_03 + - If your software architectural design of the component includes processes and tasks, are their scheduling policies and priorities (at least the needed relation one to another) defined to ensure that timing requirements are met? Please note, that the particular priorities or priority ranges will be probably defined by the project handbook or the software development plan. + + Note: see :need:`std_req__iso26262__software_743` + - Give a reason for these scheduling policies and priorities or explain why not needed. + - + - + - + + +.. attention:: + This checklist remains in draft until formal inspection is executed. + +Note: If a Review ID is not applicable for your architecture, then state ""n/a" in status and comment accordingly in remarks. + +The following static views in "valid" state and with "inspected" tag set are in the scope of this inspection: + +.. needtable:: + :filter: "iav_primula" in docname and "architecture" in docname and docname is not None and status == "valid" + :style: table + :types: comp_arc_sta + :tags: iav_primula + :columns: id;status;tags + :colwidths: 25,25,25 + :sort: title + +and the following dynamic views: + +.. needtable:: + :filter: "iav_primula" in docname and "architecture" in docname and docname is not None and status == "valid" + :style: table + :types: comp_arc_dyn + :tags: iav_primula + :columns: id;status;tags + :colwidths: 25,25,25 + :sort: title diff --git a/score/iav_primula/docs/architecture/component_architecture.rst b/score/iav_primula/docs/architecture/component_architecture.rst new file mode 100644 index 000000000..71bf50d48 --- /dev/null +++ b/score/iav_primula/docs/architecture/component_architecture.rst @@ -0,0 +1,122 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Component Architecture Documentation +==================================== + +.. document:: IAV Primula Architecture + :id: doc__iav_primula_architecture + :status: draft + :safety: QM + :security: NO + :realizes: wp__component_arch + :tags: iav_primula + + +Overview +-------- + +The IAV Primula component is a lightweight Rust library exposing one public API +to return a deterministic baseline message. + +Requirements Linked to Component Architecture +--------------------------------------------- + +.. code-block:: none + + .. needtable:: Overview of Component Requirements + :style: table + :columns: title;id + :filter: search("comp_arch_sta__archdes$", "fulfils_back") + :colwidths: 70,30 + +Description +----------- + +The component currently has no internal sub-components. Public API and +implementation are both located in ``src/lib.rs``. + +Design constraints: + +- Keep API deterministic and side-effect free. +- Keep implementation simple for initial onboarding and traceability. + +Rationale Behind Architecture Decomposition +******************************************* + +No decomposition into lower-level components is introduced in this initial +version because complexity is low and responsibilities are clear. + +.. note:: Common decisions across components / cross cutting concepts is at the higher level. + +Static Architecture +------------------- + +The components are designed to cover the expectations from the feature architecture +(i.e. if already exists a definition it should be taken over and enriched). + +A component can optional also consist of lower level components to further structure the architecture. The component and its static views can also optionally use interfaces provided by other components. + +.. comp:: IAV Primula + :id: comp__iav_primula + :security: NO + :safety: QM + :status: valid + :belongs_to: feat__security_crypto + +.. comp_arc_sta:: IAV Primula Static View + :id: comp_arc_sta__iav_primula__sv + :security: NO + :safety: QM + :status: valid + :belongs_to: comp__iav_primula + :fulfils: comp_req__iav_primula__provide_hello_message, comp_req__iav_primula__return_stable_baseline_text + + .. needarch:: + :scale: 50 + :align: center + + {{ draw_component(need(), needs) }} + +Dynamic Architecture +-------------------- + +.. comp_arc_dyn:: IAV Primula Dynamic View + :id: comp_arc_dyn__iav_primula__dv + :security: NO + :safety: QM + :status: valid + :belongs_to: comp__iav_primula + :fulfils: comp_req__iav_primula__provide_hello_message + + Caller invokes ``get_hello_message()`` and receives the constant baseline + string response immediately. + +Interfaces +---------- + +.. real_arc_int:: Public hello message interface + :id: real_arc_int__iav_primula__get_hello_message + :security: NO + :safety: QM + :fulfils: comp_req__iav_primula__provide_hello_message + :language: rust + +Internal Components +------------------- + +No internal components are defined in this baseline version. + +.. note:: + Architecture can be split into multiple files. At component level the public interfaces to be used by the user and tester to be shown. diff --git a/score/iav_primula/docs/architecture/index.rst b/score/iav_primula/docs/architecture/index.rst new file mode 100644 index 000000000..3ea0100b1 --- /dev/null +++ b/score/iav_primula/docs/architecture/index.rst @@ -0,0 +1,23 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _component_architecture_template: + +Component Architecture +====================== + +.. toctree:: + + component_architecture + chklst_arc_inspection diff --git a/score/iav_primula/docs/component_classification.rst b/score/iav_primula/docs/component_classification.rst new file mode 100644 index 000000000..7764d4998 --- /dev/null +++ b/score/iav_primula/docs/component_classification.rst @@ -0,0 +1,188 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Component Classification +======================== + +.. note:: Document header + +.. document:: IAV Primula Component Classification + :id: doc__iav_primula_comp_class + :status: draft + :safety: QM + :security: NO + :realizes: wp__sw_component_class + :tags: iav_primula + +| Classification of ``iav_primula`` +| +| GitHub: ``https://github.com/eclipse-score/inc_security_crypto/tree/main/score/t.b.d`` +| +| Additional documentation considered: +| - ``docs/index.rst`` +| - ``docs/requirements/requirements.rst`` +| - ``docs/architecture/component_architecture.rst`` + + +Step 1: Determine (P): the uncertainty of the Processes applied +--------------------------------------------------------------- + +| Apply the process measures to determine (P). +| The result of a process measure shall have as outcome [HE, PE, NE] +| - HE: High Evidence +| - PE: Partly Evidence but Manageable +| - NE: No Evidence + +.. list-table:: Determine (P) + :header-rows: 1 + + * - Id + - Indicator for applying process + - Result + - Rationale for result + + * - 1 + - Are rules, state-of-the art processes applied for the design, implementation and verification? + - HE + - Basic project rules are applied (Rust 2021 crate, tests, standard docs structure). + + * - 2 + - Are requirements available? + - HE + - Initial component requirements are documented. + + * - 3 + - Are specifications for functionalities and properties available (architecture)? + - HE + - Initial component architecture documentation is available. + + * - 4 + - Are design specifications available? + - HE + - Detailed design baseline exists for current low complexity scope. + + * - 5 + - Are configuration specification and data available, if applicable? + - HE + - No dedicated configuration data is currently required. + + * - 6 + - Are verification measures including tests and reports available? + - HE + - Hello-world test exists and verifies expected output. + + +| (P=1) shall be selected when none of the determined process measures indicate PE or NE. +| (P=2) shall be selected when at least one of the determined process measures indicate PE or NE, but the gaps evaluated are acceptable, means +| the risk of systematic faults due to these gaps is sufficiently low or manageable by mitigating the gaps. +| (P=3) in all other cases. + +``iav_primula`` is determined as ``P=1`` + + +Step 2: Determine (C): the uncertainty of finding systematic faults based on the Complexity +------------------------------------------------------------------------------------------- + +| Apply the complexity measures to determine (C). +| The result of a complexity measure shall have as outcome [NH, HM, NM] +| - NH: Not High +| - HM: High but Manageable +| - NM: high and Not Manageable +| +| **Complexity measure for programming language: RUST** + +.. list-table:: Determine (C) for RUST + :header-rows: 1 + + * - Id + - Indicator for high Complexity + - Complexity measure Tool + - Result + - Number + + * - 1 + - High amount of Lines of Code + - Lines of Code (without comments) (generated code is excluded, e.g. ProtoCmpl) + - NH + - 1 function + + * - 2 + - Unsafe code used / total unsafe code + - Count: + * LoUC+N: lines of unsafe code with safety note + * LoUC : lines of unsafe code, no safety note + - NH + - 0 + + * - 3 + - | Test exists / Coverage (Function, Line) + | (maybe better: testability, but how to measure?) + - Existing Tests Coverage + - NH + - 1 test present + + * - 4 + - High amount of public function interfaces + - Number of public function interfaces + - NH + - 1 public function + + * - 5 + - High amount of function parameters + - Number of parameters + - NH + - 0 parameters for public API + + +| (C=1) shall be selected when none of the determined complexity measures indicate HM or NM. +| (C=2) shall be selected when at least one of the determined complexity measures indicate HM or NM, but the gaps evaluated are acceptable, means +| the risk of systematic faults due to these gaps is sufficiently low in the context of the project or manageable by mitigating the gaps. +| (C=3) in all other cases. +| + +``iav_primula`` is determined as ``C=1`` + + +Step 3: Determine (CLAS_OUT): the classification outcome +-------------------------------------------------------- + +| Select CLAS_OUT depending on the determined values of (C) and (P) + ++-------+-----------------------+ +| ( C ) | ( P ) | ++-------+-------+-------+-------+ +| | 1 | 2 | 3 | ++=======+=======+=======+=======+ +| 1 | Q | Q | QR | ++-------+-------+-------+-------+ +| 2 | QR | QR | QR | ++-------+-------+-------+-------+ +| 3 | QR | QR | NQ | ++-------+-------+-------+-------+ + +``iav_primula`` is classified as ``CLAS_OUT=Q`` + + +Step 4: Document all results and rationale for choosing (P) and (C) and (CLAS_OUT) +---------------------------------------------------------------------------------- +This document + + +Step 5: Based on (CLAS_OUT) select the activities +------------------------------------------------- + +| As soon as the change request containing this is in status "Accepted", the module safety plan for the component development is adapted based on the following: (select according to above result) +| - Q: Follow the processes for qualification of software components in a safety context. +| - QR: Follow the process for pre-existing software architectural elements +| - NQ: Do no use this element in safety context diff --git a/score/iav_primula/docs/detailed_design/chklst_impl_inspection.rst b/score/iav_primula/docs/detailed_design/chklst_impl_inspection.rst new file mode 100644 index 000000000..208753ee4 --- /dev/null +++ b/score/iav_primula/docs/detailed_design/chklst_impl_inspection.rst @@ -0,0 +1,117 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. document:: IAV Primula Implementation Inspection Checklist + :id: doc__iav_primula_impl_inspection + :status: draft + :safety: QM + :security: NO + :realizes: wp__sw_implementation_inspection + :tags: iav_primula + +Implementation Inspection Checklist +=================================== + +Purpose +------- + +The purpose of this checklist is to collect the topics to be checked during implementation, +i.e. in the detailed design and the source code of the units. + +The checklist shall be agnostic to which programming language is used. Differences shall be treated +by linking to C++ or Rust specific documentation. + +Conduct +------- + +As described in the concept :need:`doc_concept__wp_inspections` the following "inspection roles" are expected to be filled: + +- content responsible (author): +- reviewer: +- moderator: + +Current state: formal implementation inspection not executed yet. + +Checklist +--------- + +It is mandatory to fill in the "passed" column with "yes" or "no" for each checklist item and additionally to add in the remarks why it is passed or not passed. +In case of "no" an issue link to the issue tracking system has to be added in the last column (if not solved in the same issue). +See also :need:`doc_concept__wp_inspections` for further information about reviews in general and inspection in particular. + +.. list-table:: Implementation Checklist + :header-rows: 1 + :widths: 10,30,50,6,6,8 + + * - Review ID + - Acceptance Criteria + - Guidance + - Passed + - Remarks + - Issue link + * - IMPL_01_01 + - Is the design according to guidelines? + - see :need:`gd_temp__detailed_design` and :need:`doc_concept__imp_concept` + (e.g. are the views done with the proposed UML diagrams) + - + - + - + * - IMPL_01_02 + - Is the implementation according to specification? + - Check if the linked component requirements are fulfilled + and detailed design also matches architecture description. + - + - + - + * - IMPL_01_03 + - Are the design decisions and constraints documented? + - Check also for plausibility of these. + - + - + - + * - IMPL_01_04 + - Are all external libraries used by the component specified in the detailed design? + - Check the automated dependency analysis. + Also make sure ASIL rated units also only use ASIL rated libraries. + - + - + - + * - IMPL_02_01 + - Are the static and dynamic code analysis reports verified for violations? + - All violations in ASIL related code must be justified. This includes the checks of coding guidelines. + - + - + - + * - IMPL_02_02 + - Do manual checks, that are derived from the coding guideline, find no safety critical error? + - Check this for the programming language used (e.g. C++ , Rust ) + - + - + - + * - IMPL_03_01 + - Do the UID of the interface in component documentation match the implemented interface names of the unit? + - Compare interface UIDs (which contains the interface name) in component architecture/detailed design documentation + with public interfaces in source code (e.g. API headers, traits, public types/functions). + - + - + - + * - IMPL_03_02 + - Are detailed design and source code consistent and is the respective traceability established ? + - Check if available static and dynamic design diagrams and the textual descriptions match the code + (e.g. naming of interfaces, units, functions/operations/messages, data types). + Check if the folder/file names of the units and its source code matches the intended functionality. + For example if a unit is named "communication" it should not contain code for "data processing". + - + - + - diff --git a/score/iav_primula/docs/detailed_design/dd_example_ex_dyn.puml b/score/iav_primula/docs/detailed_design/dd_example_ex_dyn.puml new file mode 100644 index 000000000..f96db1bf8 --- /dev/null +++ b/score/iav_primula/docs/detailed_design/dd_example_ex_dyn.puml @@ -0,0 +1,37 @@ +/' + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* +'/ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* +@startuml dd_example_ex_dyn +title Detailed Design Example Dynamic View + +participant unit1 +participant unit2 + +unit1 -> unit2 : call +unit2 --> unit1 : result + +@enduml diff --git a/score/iav_primula/docs/detailed_design/dd_example_ex_sta.puml b/score/iav_primula/docs/detailed_design/dd_example_ex_sta.puml new file mode 100644 index 000000000..8300d3c9f --- /dev/null +++ b/score/iav_primula/docs/detailed_design/dd_example_ex_sta.puml @@ -0,0 +1,37 @@ +/' + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* +'/ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +@startuml dd_example_ex_sta +title Detailed Design Example Static View + +component unit1 +component unit2 + +unit1 --> unit2 : uses + +@enduml diff --git a/score/iav_primula/docs/detailed_design/detailed_design_example.rst b/score/iav_primula/docs/detailed_design/detailed_design_example.rst new file mode 100644 index 000000000..a65c77ebe --- /dev/null +++ b/score/iav_primula/docs/detailed_design/detailed_design_example.rst @@ -0,0 +1,87 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +IAV Primula Detailed Design +=========================== + +.. document:: IAV Primula Detailed Design + :id: doc__iav_primula_detailed_design + :status: draft + :safety: QM + :security: NO + :realizes: wp__sw_implementation + :tags: iav_primula + +Detailed Design for Component: IAV Primula +========================================== + +Description +----------- + +The implementation is intentionally small and centralized in ``src/lib.rs``. + +Design constraints: + +- Keep public API simple for onboarding. +- Keep deterministic output for stable first tests. +- Avoid unnecessary abstractions until additional behavior is introduced. + +Current unit split: + +- ``src/lib.rs``: public API and implementation of ``get_hello_message()``. + +Rationale Behind Decomposition into Units +****************************************** +No further unit decomposition is needed at this stage. + +.. note:: Reason for split into multiple units could be- + - Based on design principles like SOLID,DRY etc + - Based on design pattern's etc. + +Static Diagrams for Unit Interactions +------------------------------------- + +A static view provides an overview of the units and their relationships using +UML 2.0 notations (e.g. class diagrams, component diagrams). Use ``.. uml::`` +or ``.. image::`` directives to include the diagram. + +For this first baseline implementation no additional static UML is required. + +Dynamic Diagrams for Unit Interactions (optional) +-------------------------------------------------- + +A dynamic view illustrates how the units within a component interact over their +interfaces to fulfill a specific use case or functionality. It is optional when the +component's behaviour is straightforward and can be understood from the static view +and interface documentation alone. + +Use standard UML behavioural diagrams (sequence diagrams, state machine diagrams) +with ``.. uml::`` or ``.. image::`` directives. + +For this first baseline implementation no additional dynamic UML is required. + +Units within the Component +-------------------------- + +The relationship between a unit and its parent component is established implicitly +through the file path. Each component has its own directory, and units residing +within that directory belong to it. The unit's attributes and behaviour are documented +in the source code itself. A separate static diagram per unit is not required. + +Interface documentation of a software unit is part of the source code (e.g. public +API headers, trait definitions, or documented function signatures). + +Current unit list: + +- ``lib.rs``: returns constant hello message string. diff --git a/score/iav_primula/docs/detailed_design/index.rst b/score/iav_primula/docs/detailed_design/index.rst new file mode 100644 index 000000000..61199c521 --- /dev/null +++ b/score/iav_primula/docs/detailed_design/index.rst @@ -0,0 +1,42 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _component_detailed_design_template: + +Detailed Design +############### + +.. attention:: + + The detailed design document is optional and should be created if the design of the component is complex and cannot be easily understood from the architecture documentation and interface documentation alone. + But the inspection checklist for the implementation is mandatory. + + +Detail design example +--------------------- + +An example of documenting detailed design can be found in: + + .. toctree:: + + detailed_design_example + +Inspection Checklist +-------------------- + +The checklist for verification of the detailed design and code can be found here: + +.. toctree:: + + chklst_impl_inspection diff --git a/score/iav_primula/docs/index.rst b/score/iav_primula/docs/index.rst new file mode 100644 index 000000000..be8911dfa --- /dev/null +++ b/score/iav_primula/docs/index.rst @@ -0,0 +1,201 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _component_template: + +IAV Primula Component +##################### + +.. note:: Document header + +.. document:: IAV Primula Component + :id: doc__iav_primula + :status: draft + :safety: QM + :security: NO + :realizes: wp__cmpt_request + :tags: iav_primula + +.. comp:: IAV Primula + :id: comp__iav_primula + :security: NO + :safety: QM + :status: valid + +Abstract +======== + +IAV_Primula is a cryptographic driver in Rust focused on integrating +post-quantum (PQ) algorithms and establishing a future-ready foundation for +cryptographic processing in the S-CORE context. The component emphasizes a +clear, robust, and maintainable architecture that provides safe and structured +integration paths for quantum-resistant methods. At the current planning stage, +integrating classical cryptographic algorithms is not intended; the initial +scope is fully focused on PQ-based capabilities and their clean technical +embedding. + +The cryptodriver is designed around a consistent job-processing model. The +offered processing jobs include, among others, Signature Generate, Signature +Verification, Key Generate, and Key Exchange. Processing is intended to follow +clearly defined interfaces and traceable request/response flows, enabling +integrators to use cryptographic operations and key-related processes in a +uniform way. Extensibility is also considered from the beginning so that +additional PQ algorithms and operations can be added in a controlled manner. + +By being implemented in Rust, IAV_Primula benefits from strong memory-safety +properties and improved robustness against common implementation errors. +Overall, the component addresses the need for a modern, integration-friendly, +and post-quantum-focused cryptographic driver baseline designed for long-term +security and structured evolution. + + +Rationale +========= + +The initial implementation is intentionally minimal. A deterministic and +side-effect-free function allows us to validate repository setup, Rust crate +integration, and first test execution with very low complexity. + +.. note:: + The rationale should provide evidence of consensus within the community and discuss important objections or concerns raised during discussion. + For the documentation of the decision the :need:`gd_temp__change_decision_record` can be used. + +Specification +============= + +The component currently provides a single public interface: + +- ``get_hello_message() -> &'static str`` + +The requirement, architecture, and implementation inspection preparation are +documented in the linked sub-documents. + + +Backwards Compatibility +======================= + +No backwards compatibility impact is expected at this stage. The component is +new and currently has no consumers with compatibility constraints. + + +Security Impact +=============== + +No relevant security impact is identified for the current scope. The API +returns a constant string and performs no external interaction. + +.. note:: + If there are security concerns in relation to the CR, those concerns should be explicitly written out to make sure reviewers of the CR are aware of them. + +Which security requirements are affected or has to be changed? +Could the new/modified component enable new threat scenarios? +Could the new/modified component enable new attack paths? +Could the new/modified component impact functional safety? +If applicable, which additional security measures must be implemented to mitigate the risk? + +.. note:: + Use Security Software Critically Analysis, Vulnerability Analysis. + [Methods will be defined later in Process area Security Analysis] + + +Safety Impact +============= + +No safety impact is identified for the current scope. The component is +classified as ``QM`` and currently does not implement safety mechanisms. + +.. note:: + If there are safety concerns in relation to the CR, those concerns should be explicitly written out to make sure reviewers of the CR are aware of them. + +Which safety requirements are affected or has to be changed? +Could the new/modified component be a potential common cause or cascading failure initiator? +If applicable, which additional safety measures must be implemented to mitigate the risk? + +.. note:: + Use Dependency Failure Analysis and/or Safety Software Critically Analysis. + [Methods will be defined later in Process area Safety Analysis] + +For new feature/component contributions: + +- Expected ASIL level: ``QM`` +- Expected classification of the contribution: preliminary ``Q`` + +.. note:: + Use the component classification method here to classify your component, if it shall to be used in a safety context: :need:`gd_temp__component_classification`. + +License Impact +============== + +No additional license impact is currently expected. Implementation is original +project code under Apache-2.0. + + +How to Teach This +================= + +Use the component as a simple Rust library baseline and reference the test +``returns_expected_message`` as a minimal example for unit/integration flow. + +.. note:: + For a CR that adds new functionality or changes behaviour, it is helpful to include a section on how to teach users, new and experienced, how to apply the CR to their work. + +Rejected Ideas +============== + +No alternatives were evaluated yet due to the intentionally small first scope. + +.. note:: + Throughout the discussion of a CR, various ideas will be proposed which are not accepted. + Those rejected ideas should be recorded along with the reasoning as to why they were rejected. + This both helps record the thought process behind the final version of the CR as well as preventing people from bringing up the same rejected idea again in subsequent discussions. + In a way this section can be thought of as a breakout section of the Rationale section that is focused specifically on why certain ideas were not ultimately pursued. + + + +Open Issues +=========== + +- Extend API beyond baseline hello message. +- Decide whether detailed design document remains needed after growth. +- Confirm if safety analysis artifacts are required once safety-relevant + behavior is introduced. + +.. note:: + While a CR is in draft, ideas can come up which warrant further discussion. + Those ideas should be recorded so people know that they are being thought about but do not have a concrete resolution. + This helps make sure all issues required for the CR to be ready for consideration are complete and reduces people duplicating prior discussion. + + + +Footnotes +========= + +None. + + +Further Documentation of the component can be found in the following sections: + +Component Detail Information +============================ + +.. toctree:: + :maxdepth: 1 + + architecture/index + detailed_design/index + requirements/index + safety_analysis/dfa + safety_analysis/fmea + safety_analysis/aou_requirements_template + component_classification diff --git a/score/iav_primula/docs/manuals/.gitkeep b/score/iav_primula/docs/manuals/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/score/iav_primula/docs/requirements/chklst_req_inspection.rst b/score/iav_primula/docs/requirements/chklst_req_inspection.rst new file mode 100644 index 000000000..140691383 --- /dev/null +++ b/score/iav_primula/docs/requirements/chklst_req_inspection.rst @@ -0,0 +1,178 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + + +.. document:: IAV Primula Requirements Inspection Checklist + :id: doc__iav_primula_req_inspection + :status: draft + :safety: QM + :security: NO + :realizes: wp__requirements_inspect + :tags: iav_primula + +Requirement Inspection Checklist +================================ + +Purpose +------- + +The purpose of this requirement inspection checklist is to collect the topics to be checked during requirements inspection. + +Conduct +------- + +As described in the concept :need:`doc_concept__wp_inspections` the following "inspection roles" are expected to be filled: + +- content responsible (author): +- reviewer: +- moderator: +- test expert: + +Current state: formal requirement inspection not executed yet. + +Checklist +--------- + +It is mandatory to fill in the "passed" column with "yes" or "no" for each checklist item and additionally to add in the remarks why it is passed or not passed. +In case of "no" an issue link to the issue tracking system has to be added in the last column (if not solved in the same issue). +See also :need:`doc_concept__wp_inspections` for further information about reviews in general and inspection in particular. + +.. list-table:: Component Requirement Inspection Checklist + :header-rows: 1 + :widths: 10,30,50,6,6,8 + + * - Review ID + - Acceptance Criteria + - Guidance + - Passed + - Remarks + - Issue link + * - REQ_01_01 + - Is the requirement formulation template used? + - see :need:`gd_temp__req_formulation`, this includes the use of "shall". + - + - + - + * - REQ_02_01 + - Is the requirement description *comprehensible* ? + - If you think the requirement is hard to understand, comment here. + - + - + - + * - REQ_02_02 + - Is the requirement description *unambiguous* ? + - Especially search for "weak words" like "about", "etc.", "relevant" and others (see the internet documentation on this). This check shall be supported by tooling. + - + - + - + * - REQ_02_03 + - Is the requirement description *atomic* ? + - A good way to think about this is to consider if the requirement may be tested by one (positive) test case or needs more of these. The requirement formulation template should also avoid being non-atomic already. Note that there are cases where also non-atomic requirements are the better ones, for example if those are better understandable. + - + - + - + * - REQ_02_04 + - Is the requirement description *feasible* ? + - If at the time of the inspection the requirement has already some implementation, the answer is yes. This can be checked via traces, but also :need:`gd_req__req_attr_impl` shows this. In case the requirement has no implementation at the time of inspection (i.e. not implemented at least as "proof-of-concept"), a development expert should be invited to the Pull-Request review to explicitly check this item. + - + - + - + * - REQ_02_05 + - Is the requirement description *independent from implementation* ? + - This checkpoint should improve requirements definition in the sense that the "what" is described and not the "how" - the latter should be described in architecture/design derived from the requirement. But there can also be a good reason for this, for example we would require using a file format like JSON and even specify the formatting standard already on stakeholder requirement level because we want to be compatible. A finding in this checkpoint does not mean there is a safety problem in the requirement. + - + - + - + * - REQ_03_01 + - Is the *linkage to the parent requirement* correct? + - Linkage to correct levels and ASIL attributes is checked automatically, but it needs checking if the child requirement implements (at least) a part of the parent requirement. + - + - + - + * - REQ_04_01 + - Is the requirement *internally and externally consistent*? + - Does the requirement contradict other requirements within the same or higher levels? One may restrict the search to the feature for component requirements, for features to other features using same components. Is the description of the requirement consistent with all its attributes (if not already part of another check, e.g. does the title fit?). + - + - + - + * - REQ_05_01 + - Do the software requirements consider *timing constraints*? + - This checkpoint encourages to think about timing constraints even if those are not explicitly mentioned in the parent requirement. If the reviewer of a requirement already knows or suspects that the code execution will be consuming a lot of time, one should think of the expectation of a "user". + - + - + - + * - REQ_06_01 + - Does the requirement consider *external interfaces*? + - The SW platform's external interfaces (to the user) are defined in the Feature Architecture, so the Feature and Component Requirements should determine the input data use and setting of output data for these interfaces. Are all output values defined? + - + - + - + * - REQ_07_01 + - Is the *safety* attribute set correctly? + - Derived requirements are checked automatically, see :need:`gd_req__req_linkage_safety`. But for the top level requirements (and also all AoU) this needs to be checked manually for correctness. + - + - + - + * - REQ_07_02 + - Is the attribute *security* set correctly? + - For component requirements this checklist item is supported by automated check: "Every requirement which satisfies a feature requirement with security attribute set to YES inherits this". But the component requirements/architecture may additionally also be subject to a :need:`wp__sw_component_security_analysis`. + - + - + - + * - REQ_08_01 + - Is the requirement *verifiable*? + - If at the time of the inspection already tests are created for the requirement, the answer is yes. This can be checked via traces, but also :need:`gd_req__req_attr_test_covered` shows this. In case the requirement is not sufficiently traced to test cases already, a test expert is invited to the inspection to give their opinion whether the requirement is formulated in a way that supports test development and the available test infrastructure is sufficient to perform the test. + - + - + - + * - REQ_08_02 + - Is the requirement verifiable by design or code review in case it is not feasibly testable? + - In very rare cases a requirement may not be verifiable by test cases, for example a specific non-functional requirement. In this case a requirement analysis verifies the requirement by design/code review. If such a requirement is in scope of this inspection, please check this here and link to the respective review record. A test expert is invited to the inspection to confirm their opinion that the requirement is not testable. + - + - + - + * - REQ_09_01 + - Do the requirements that define a safety mechanism specify the error reaction leading to a safe state? + - Alternatively to the safe state there could also be "repair" mechanisms. Also do not forget to consider REQ_05_01 for these. + - + - + - + + +.. attention:: + This checklist remains in draft until formal inspection is executed. + +Note: If a Review ID is not applicable for your requirement, then state ""n/a" in status and comment accordingly in remarks. + +The following requirements in "valid" state and with "inspected" tag set are in the scope of this inspection: + +.. needtable:: + :filter: "iav_primula" in docname and "requirements" in docname and docname is not None and status == "valid" + :style: table + :types: comp_req + :tags: iav_primula + :columns: id;status;tags + :colwidths: 25,25,25 + :sort: title + +And also the following AoUs in "valid" state and with "inspected" tag set (for these please answer the questions above as if the AoUs are requirements, except question REQ_03_01): + +.. needtable:: + :filter: "iav_primula" in docname and "requirements" in docname and docname is not None and status == "valid" + :style: table + :types: aou_req + :tags: iav_primula + :columns: id;status;tags + :colwidths: 25,25,25 + :sort: title diff --git a/score/iav_primula/docs/requirements/index.rst b/score/iav_primula/docs/requirements/index.rst new file mode 100644 index 000000000..9eea1fc74 --- /dev/null +++ b/score/iav_primula/docs/requirements/index.rst @@ -0,0 +1,21 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Requirements +############ + +.. toctree:: + + requirements + chklst_req_inspection diff --git a/score/iav_primula/docs/requirements/requirements.rst b/score/iav_primula/docs/requirements/requirements.rst new file mode 100644 index 000000000..4d0f07285 --- /dev/null +++ b/score/iav_primula/docs/requirements/requirements.rst @@ -0,0 +1,76 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +IAV Primula Requirements +######################## + +.. document:: IAV Primula Requirements + :id: doc__iav_primula_requirements + :status: draft + :safety: QM + :security: NO + :realizes: wp__requirements_comp[version==1] + :tags: iav_primula + +Scope +===== + +Functional Requirements +----------------------- + +.. comp_req:: Provide hello message function + :id: comp_req__iav_primula__provide_hello_message + :reqtype: Functional + :security: NO + :safety: QM + :derived_from: feat_req__security_crypto__hello_world_baseline + :status: valid + :satisfied_by: comp__iav_primula + + The component shall provide a public Rust function + ``get_hello_message() -> &'static str``. + +.. Note: + ``get_hello_message()`` shall return the exact value + ``"Hello World from iav_primula"``. + +Assumption of Use Requirements +------------------------------ + +.. aou_req:: Integrate as Rust library API + :id: aou_req__iav_primula__integrate_as_rust_library_api + :reqtype: Process + :security: NO + :safety: QM + :status: valid + + The component user shall link the crate ``iav_primula`` and call the public + API from Rust code. + +Environmental Requirements +-------------------------- + +.. aou_req:: Build environment supports Rust 2021 + :id: aou_req__iav_primula__build_env_supports_rust_2021 + :reqtype: Process + :security: NO + :safety: QM + :status: valid + :tags: environment + + The component shall be built in an environment that supports Rust edition + 2021, consistent with the component BUILD definition. + +.. needextend:: is_external == False and "iav_primula" in id + :+tags: iav_primula diff --git a/score/iav_primula/docs/safety_analysis/aou_requirements_template.rst b/score/iav_primula/docs/safety_analysis/aou_requirements_template.rst new file mode 100644 index 000000000..054dbea1b --- /dev/null +++ b/score/iav_primula/docs/safety_analysis/aou_requirements_template.rst @@ -0,0 +1,42 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +AoU Component Requirements Snippets +=================================== + +This page contains the current Assumptions of Use snippets used by IAV Primula. + +Component AoU +------------- + +.. code-block:: rst + + .. aou_req:: Integrate as Rust library API + :id: aou_req__iav_primula__integrate_as_rust_library_api + :reqtype: Process + :security: NO + :safety: QM + :status: valid + + The component user shall link the crate ``iav_primula`` and call the public API from Rust code. + + .. aou_req:: Build environment supports Rust 2021 + :id: aou_req__iav_primula__build_env_supports_rust_2021 + :reqtype: Process + :security: NO + :safety: QM + :status: valid + :tags: environment + + The component shall be built in an environment that supports Rust edition 2021. \ No newline at end of file diff --git a/score/iav_primula/docs/safety_analysis/dfa.rst b/score/iav_primula/docs/safety_analysis/dfa.rst new file mode 100644 index 000000000..0cd1f02e9 --- /dev/null +++ b/score/iav_primula/docs/safety_analysis/dfa.rst @@ -0,0 +1,36 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + + +DFA (Dependent Failure Analysis) +================================ + +.. document:: IAV Primula DFA + :id: doc__iav_primula_dfa + :status: draft + :safety: QM + :security: NO + :realizes: wp__sw_component_dfa + :tags: iav_primula + +.. note:: + Current component scope is ``QM`` and contains only a deterministic pure + function returning a constant string. No dependent-failure initiators are + identified for this baseline. + +Dependent Failure Initiators +---------------------------- + +No ``comp_saf_dfa`` entries are required for the current baseline implementation. +Re-evaluate and add entries once safety-relevant behavior is introduced. \ No newline at end of file diff --git a/score/iav_primula/docs/safety_analysis/fmea.rst b/score/iav_primula/docs/safety_analysis/fmea.rst new file mode 100644 index 000000000..dad997f63 --- /dev/null +++ b/score/iav_primula/docs/safety_analysis/fmea.rst @@ -0,0 +1,108 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + + +FMEA (Failure Modes and Effects Analysis) +========================================= + +.. document:: IAV Primula FMEA + :id: doc__iav_primula_fmea + :status: draft + :safety: QM + :security: NO + :realizes: wp__sw_component_fmea + :tags: iav_primula + +.. note:: + Current component scope is ``QM`` and contains only deterministic in-process + string return behavior. The generic fault model is recorded as not applicable + for this baseline. + +Failure Mode List +----------------- + +.. list-table:: Fault Models for sequence diagrams + :header-rows: 1 + :widths: 10,20,10,20 + + * - ID + - Failure Mode + - Applicability + - Rationale + * - MF_01_01 + - message is not received (is a subset/more precise description of MF_01_05) + - no + - No inter-component messaging in current scope. + * - MF_01_02 + - message received too late (only relevant if delay is a realistic fault) + - no + - No timing-critical communication path in current scope. + * - MF_01_03 + - message received too early (usually not a problem) + - no + - No timing-dependent message protocol is implemented. + * - MF_01_04 + - message not received correctly by all recipients (different messages or messages partly lost). Only relevant if the same message goes to multiple recipients. + - no + - No fan-out message distribution exists. + * - MF_01_05 + - message is corrupted + - no + - No message transport layer in current scope. + * - MF_01_06 + - message is not sent + - no + - No send operation is implemented. + * - MF_01_07 + - message is unintended sent + - no + - Component does not emit external messages. + * - CO_01_01 + - minimum constraint boundary is violated + - no + - No numerical safety boundary handling in current scope. + * - CO_01_02 + - maximum constraint boundary is violated + - no + - No numerical safety boundary handling in current scope. + * - EX_01_01 + - Process calculates wrong result(s) (subset of data corruption faults) + - no + - Function returns a fixed literal without algorithmic processing. + * - EX_01_02 + - processing too slow (only relevant if timing is considered) + - no + - No timing requirement allocated to current baseline function. + * - EX_01_03 + - processing too fast (only relevant if timing is considered) + - no + - No minimum timing constraint allocated. + * - EX_01_04 + - loss of execution + - no + - Not safety-relevant in current ``QM`` scope. + * - EX_01_05 + - processing changes to arbitrary process + - no + - No process control behavior is implemented. + * - EX_01_06 + - processing is not complete (infinite loop) + - no + - Function body is finite and constant. + +FMEA +---- + +No ``comp_saf_fmea`` entries are required for the current baseline. +Re-evaluate this document once safety-relevant behavior is introduced. \ No newline at end of file diff --git a/score/iav_primula/docs/security_analysis/.gitkeep b/score/iav_primula/docs/security_analysis/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/score/iav_primula/src/details/.gitkeep b/score/iav_primula/src/details/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/score/iav_primula/src/main.rs b/score/iav_primula/src/main.rs new file mode 100644 index 000000000..e0f149a92 --- /dev/null +++ b/score/iav_primula/src/main.rs @@ -0,0 +1,16 @@ +// ******************************************************************************* +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// +// +// SPDX-License-Identifier: Apache-2.0 +// ******************************************************************************* + +pub fn get_hello_message() -> &'static str { + "Hello World from iav_primula" +} diff --git a/score/iav_primula/tests/.gitkeep b/score/iav_primula/tests/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/score/iav_primula/tests/BUILD b/score/iav_primula/tests/BUILD new file mode 100644 index 000000000..1bf65a3d9 --- /dev/null +++ b/score/iav_primula/tests/BUILD @@ -0,0 +1,21 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@rules_rust//rust:defs.bzl", "rust_test") + +rust_test( + name = "hello_test", + srcs = ["hello_test.rs"], + edition = "2021", + deps = ["//score/iav_primula"], +) diff --git a/score/iav_primula/tests/hello_test.rs b/score/iav_primula/tests/hello_test.rs new file mode 100644 index 000000000..b211f69cd --- /dev/null +++ b/score/iav_primula/tests/hello_test.rs @@ -0,0 +1,19 @@ +// ******************************************************************************* +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// +// +// SPDX-License-Identifier: Apache-2.0 +// ******************************************************************************* + +use iav_primula::get_hello_message; + +#[test] +fn returns_expected_message() { + assert_eq!(get_hello_message(), "Hello World from iav_primula"); +} diff --git a/score/iav_primula/tests/integration_tests/.gitkeep b/score/iav_primula/tests/integration_tests/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/tests/iav_primula/BUILD b/tests/iav_primula/BUILD new file mode 100644 index 000000000..dd481ca5d --- /dev/null +++ b/tests/iav_primula/BUILD @@ -0,0 +1,17 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +test_suite( + name = "all", + tests = ["//score/iav_primula/tests:hello_test"], +) From 4bf8ccda8754f2e7880560ddf0d1976251b4fcca Mon Sep 17 00:00:00 2001 From: "Hansen, Henrik (TT-E)" Date: Tue, 7 Jul 2026 15:04:48 +0200 Subject: [PATCH 02/12] Start to fix documentation run --- index.rst | 1 + .../docs/architecture/component_architecture.rst | 5 +---- score/iav_primula/docs/architecture/index.rst | 2 +- score/iav_primula/docs/detailed_design/index.rst | 2 +- score/iav_primula/docs/index.rst | 8 +------- score/iav_primula/docs/requirements/requirements.rst | 5 ++--- 6 files changed, 7 insertions(+), 16 deletions(-) diff --git a/index.rst b/index.rst index 33bc18e5f..d4d97bf77 100644 --- a/index.rst +++ b/index.rst @@ -212,6 +212,7 @@ For documentation of individual components within this module: :maxdepth: 1 score/component_example/docs/index + score/iav_primula/docs/index score/crypto/daemon/data_manager/docs/index Architecture Modeling Example diff --git a/score/iav_primula/docs/architecture/component_architecture.rst b/score/iav_primula/docs/architecture/component_architecture.rst index 71bf50d48..ecd66e512 100644 --- a/score/iav_primula/docs/architecture/component_architecture.rst +++ b/score/iav_primula/docs/architecture/component_architecture.rst @@ -73,7 +73,6 @@ A component can optional also consist of lower level components to further struc :security: NO :safety: QM :status: valid - :belongs_to: feat__security_crypto .. comp_arc_sta:: IAV Primula Static View :id: comp_arc_sta__iav_primula__sv @@ -81,7 +80,6 @@ A component can optional also consist of lower level components to further struc :safety: QM :status: valid :belongs_to: comp__iav_primula - :fulfils: comp_req__iav_primula__provide_hello_message, comp_req__iav_primula__return_stable_baseline_text .. needarch:: :scale: 50 @@ -98,7 +96,6 @@ Dynamic Architecture :safety: QM :status: valid :belongs_to: comp__iav_primula - :fulfils: comp_req__iav_primula__provide_hello_message Caller invokes ``get_hello_message()`` and receives the constant baseline string response immediately. @@ -110,7 +107,7 @@ Interfaces :id: real_arc_int__iav_primula__get_hello_message :security: NO :safety: QM - :fulfils: comp_req__iav_primula__provide_hello_message + :status: valid :language: rust Internal Components diff --git a/score/iav_primula/docs/architecture/index.rst b/score/iav_primula/docs/architecture/index.rst index 3ea0100b1..2011fabad 100644 --- a/score/iav_primula/docs/architecture/index.rst +++ b/score/iav_primula/docs/architecture/index.rst @@ -12,7 +12,7 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _component_architecture_template: +.. _iav_primula_component_architecture: Component Architecture ====================== diff --git a/score/iav_primula/docs/detailed_design/index.rst b/score/iav_primula/docs/detailed_design/index.rst index 61199c521..5e44dc143 100644 --- a/score/iav_primula/docs/detailed_design/index.rst +++ b/score/iav_primula/docs/detailed_design/index.rst @@ -12,7 +12,7 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _component_detailed_design_template: +.. _iav_primula_component_detailed_design: Detailed Design ############### diff --git a/score/iav_primula/docs/index.rst b/score/iav_primula/docs/index.rst index be8911dfa..68fdc6c8b 100644 --- a/score/iav_primula/docs/index.rst +++ b/score/iav_primula/docs/index.rst @@ -12,7 +12,7 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _component_template: +.. _iav_primula_component: IAV Primula Component ##################### @@ -27,12 +27,6 @@ IAV Primula Component :realizes: wp__cmpt_request :tags: iav_primula -.. comp:: IAV Primula - :id: comp__iav_primula - :security: NO - :safety: QM - :status: valid - Abstract ======== diff --git a/score/iav_primula/docs/requirements/requirements.rst b/score/iav_primula/docs/requirements/requirements.rst index 4d0f07285..82e5773de 100644 --- a/score/iav_primula/docs/requirements/requirements.rst +++ b/score/iav_primula/docs/requirements/requirements.rst @@ -34,7 +34,6 @@ Functional Requirements :reqtype: Functional :security: NO :safety: QM - :derived_from: feat_req__security_crypto__hello_world_baseline :status: valid :satisfied_by: comp__iav_primula @@ -49,7 +48,7 @@ Assumption of Use Requirements ------------------------------ .. aou_req:: Integrate as Rust library API - :id: aou_req__iav_primula__integrate_as_rust_library_api + :id: aou_req__iav_primula__rust_lib_api :reqtype: Process :security: NO :safety: QM @@ -62,7 +61,7 @@ Environmental Requirements -------------------------- .. aou_req:: Build environment supports Rust 2021 - :id: aou_req__iav_primula__build_env_supports_rust_2021 + :id: aou_req__iav_primula__rust2021_build_env :reqtype: Process :security: NO :safety: QM From 30d4e21448f72ea2456c0354276fc60eed86a7fa Mon Sep 17 00:00:00 2001 From: "Hansen, Henrik (TT-E)" Date: Wed, 8 Jul 2026 07:23:28 +0200 Subject: [PATCH 03/12] Continue with "Build Documentation" fix --- score/iav_primula/docs/architecture/component_architecture.rst | 3 +++ score/iav_primula/docs/requirements/requirements.rst | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/score/iav_primula/docs/architecture/component_architecture.rst b/score/iav_primula/docs/architecture/component_architecture.rst index ecd66e512..f8e81e82b 100644 --- a/score/iav_primula/docs/architecture/component_architecture.rst +++ b/score/iav_primula/docs/architecture/component_architecture.rst @@ -73,6 +73,7 @@ A component can optional also consist of lower level components to further struc :security: NO :safety: QM :status: valid + :belongs_to: feat__mtef .. comp_arc_sta:: IAV Primula Static View :id: comp_arc_sta__iav_primula__sv @@ -80,6 +81,7 @@ A component can optional also consist of lower level components to further struc :safety: QM :status: valid :belongs_to: comp__iav_primula + :fulfils: comp_req__iav_primula__provide_hello_message .. needarch:: :scale: 50 @@ -96,6 +98,7 @@ Dynamic Architecture :safety: QM :status: valid :belongs_to: comp__iav_primula + :fulfils: comp_req__iav_primula__provide_hello_message Caller invokes ``get_hello_message()`` and receives the constant baseline string response immediately. diff --git a/score/iav_primula/docs/requirements/requirements.rst b/score/iav_primula/docs/requirements/requirements.rst index 82e5773de..ae83f9651 100644 --- a/score/iav_primula/docs/requirements/requirements.rst +++ b/score/iav_primula/docs/requirements/requirements.rst @@ -33,7 +33,7 @@ Functional Requirements :id: comp_req__iav_primula__provide_hello_message :reqtype: Functional :security: NO - :safety: QM + :safety: ASIL_A :status: valid :satisfied_by: comp__iav_primula From 6d506a9eb7039da9e64a76c8511419b6eeabdaac Mon Sep 17 00:00:00 2001 From: "Henrik Hansen (IAV)" Date: Wed, 8 Jul 2026 07:50:39 +0200 Subject: [PATCH 04/12] Continue with "Build Documentation" fix, requirements.rst --- score/iav_primula/docs/requirements/requirements.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/score/iav_primula/docs/requirements/requirements.rst b/score/iav_primula/docs/requirements/requirements.rst index ae83f9651..5ca8e7205 100644 --- a/score/iav_primula/docs/requirements/requirements.rst +++ b/score/iav_primula/docs/requirements/requirements.rst @@ -33,7 +33,7 @@ Functional Requirements :id: comp_req__iav_primula__provide_hello_message :reqtype: Functional :security: NO - :safety: ASIL_A + :safety: ASIL_B :status: valid :satisfied_by: comp__iav_primula From 52bc10be9cdfd6a46ed186063bb1fcf485931ae0 Mon Sep 17 00:00:00 2001 From: HeHa112 <113408507+HeHa112@users.noreply.github.com> Date: Wed, 8 Jul 2026 11:48:00 +0200 Subject: [PATCH 05/12] Start to fix documentation run (#2) * "Build Documentation" fix --- index.rst | 1 + .../docs/architecture/component_architecture.rst | 6 +++--- score/iav_primula/docs/architecture/index.rst | 2 +- score/iav_primula/docs/detailed_design/index.rst | 2 +- score/iav_primula/docs/index.rst | 8 +------- score/iav_primula/docs/requirements/requirements.rst | 7 +++---- 6 files changed, 10 insertions(+), 16 deletions(-) diff --git a/index.rst b/index.rst index 33bc18e5f..d4d97bf77 100644 --- a/index.rst +++ b/index.rst @@ -212,6 +212,7 @@ For documentation of individual components within this module: :maxdepth: 1 score/component_example/docs/index + score/iav_primula/docs/index score/crypto/daemon/data_manager/docs/index Architecture Modeling Example diff --git a/score/iav_primula/docs/architecture/component_architecture.rst b/score/iav_primula/docs/architecture/component_architecture.rst index 71bf50d48..f8e81e82b 100644 --- a/score/iav_primula/docs/architecture/component_architecture.rst +++ b/score/iav_primula/docs/architecture/component_architecture.rst @@ -73,7 +73,7 @@ A component can optional also consist of lower level components to further struc :security: NO :safety: QM :status: valid - :belongs_to: feat__security_crypto + :belongs_to: feat__mtef .. comp_arc_sta:: IAV Primula Static View :id: comp_arc_sta__iav_primula__sv @@ -81,7 +81,7 @@ A component can optional also consist of lower level components to further struc :safety: QM :status: valid :belongs_to: comp__iav_primula - :fulfils: comp_req__iav_primula__provide_hello_message, comp_req__iav_primula__return_stable_baseline_text + :fulfils: comp_req__iav_primula__provide_hello_message .. needarch:: :scale: 50 @@ -110,7 +110,7 @@ Interfaces :id: real_arc_int__iav_primula__get_hello_message :security: NO :safety: QM - :fulfils: comp_req__iav_primula__provide_hello_message + :status: valid :language: rust Internal Components diff --git a/score/iav_primula/docs/architecture/index.rst b/score/iav_primula/docs/architecture/index.rst index 3ea0100b1..2011fabad 100644 --- a/score/iav_primula/docs/architecture/index.rst +++ b/score/iav_primula/docs/architecture/index.rst @@ -12,7 +12,7 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _component_architecture_template: +.. _iav_primula_component_architecture: Component Architecture ====================== diff --git a/score/iav_primula/docs/detailed_design/index.rst b/score/iav_primula/docs/detailed_design/index.rst index 61199c521..5e44dc143 100644 --- a/score/iav_primula/docs/detailed_design/index.rst +++ b/score/iav_primula/docs/detailed_design/index.rst @@ -12,7 +12,7 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _component_detailed_design_template: +.. _iav_primula_component_detailed_design: Detailed Design ############### diff --git a/score/iav_primula/docs/index.rst b/score/iav_primula/docs/index.rst index be8911dfa..68fdc6c8b 100644 --- a/score/iav_primula/docs/index.rst +++ b/score/iav_primula/docs/index.rst @@ -12,7 +12,7 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -.. _component_template: +.. _iav_primula_component: IAV Primula Component ##################### @@ -27,12 +27,6 @@ IAV Primula Component :realizes: wp__cmpt_request :tags: iav_primula -.. comp:: IAV Primula - :id: comp__iav_primula - :security: NO - :safety: QM - :status: valid - Abstract ======== diff --git a/score/iav_primula/docs/requirements/requirements.rst b/score/iav_primula/docs/requirements/requirements.rst index 4d0f07285..5ca8e7205 100644 --- a/score/iav_primula/docs/requirements/requirements.rst +++ b/score/iav_primula/docs/requirements/requirements.rst @@ -33,8 +33,7 @@ Functional Requirements :id: comp_req__iav_primula__provide_hello_message :reqtype: Functional :security: NO - :safety: QM - :derived_from: feat_req__security_crypto__hello_world_baseline + :safety: ASIL_B :status: valid :satisfied_by: comp__iav_primula @@ -49,7 +48,7 @@ Assumption of Use Requirements ------------------------------ .. aou_req:: Integrate as Rust library API - :id: aou_req__iav_primula__integrate_as_rust_library_api + :id: aou_req__iav_primula__rust_lib_api :reqtype: Process :security: NO :safety: QM @@ -62,7 +61,7 @@ Environmental Requirements -------------------------- .. aou_req:: Build environment supports Rust 2021 - :id: aou_req__iav_primula__build_env_supports_rust_2021 + :id: aou_req__iav_primula__rust2021_build_env :reqtype: Process :security: NO :safety: QM From af2a02616a81d77d1167ee75bc7659de869bba2f Mon Sep 17 00:00:00 2001 From: "Hansen, Henrik (TT-E)" Date: Fri, 10 Jul 2026 10:13:44 +0200 Subject: [PATCH 06/12] Update after review --- .../docs/architecture/chklst_arc_inspection.rst | 2 +- .../docs/architecture/component_architecture.rst | 10 +++++----- score/iav_primula/docs/component_classification.rst | 2 +- .../docs/detailed_design/chklst_impl_inspection.rst | 2 +- .../docs/detailed_design/detailed_design_example.rst | 8 ++++---- score/iav_primula/docs/index.rst | 2 +- .../docs/requirements/chklst_req_inspection.rst | 2 +- score/iav_primula/docs/requirements/requirements.rst | 6 +++--- .../docs/safety_analysis/aou_requirements_template.rst | 4 ++-- score/iav_primula/docs/safety_analysis/dfa.rst | 2 +- score/iav_primula/docs/safety_analysis/fmea.rst | 2 +- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/score/iav_primula/docs/architecture/chklst_arc_inspection.rst b/score/iav_primula/docs/architecture/chklst_arc_inspection.rst index 10562ba69..0269adbf7 100644 --- a/score/iav_primula/docs/architecture/chklst_arc_inspection.rst +++ b/score/iav_primula/docs/architecture/chklst_arc_inspection.rst @@ -17,7 +17,7 @@ :id: doc__iav_primula_arc_inspection :status: draft :safety: QM - :security: NO + :security: YES :realizes: wp__sw_arch_verification :tags: iav_primula diff --git a/score/iav_primula/docs/architecture/component_architecture.rst b/score/iav_primula/docs/architecture/component_architecture.rst index f8e81e82b..a055c20e9 100644 --- a/score/iav_primula/docs/architecture/component_architecture.rst +++ b/score/iav_primula/docs/architecture/component_architecture.rst @@ -19,7 +19,7 @@ Component Architecture Documentation :id: doc__iav_primula_architecture :status: draft :safety: QM - :security: NO + :security: YES :realizes: wp__component_arch :tags: iav_primula @@ -45,7 +45,7 @@ Description ----------- The component currently has no internal sub-components. Public API and -implementation are both located in ``src/lib.rs``. +implementation are both located in ``src/main.rs``. Design constraints: @@ -70,14 +70,14 @@ A component can optional also consist of lower level components to further struc .. comp:: IAV Primula :id: comp__iav_primula - :security: NO + :security: YES :safety: QM :status: valid :belongs_to: feat__mtef .. comp_arc_sta:: IAV Primula Static View :id: comp_arc_sta__iav_primula__sv - :security: NO + :security: YES :safety: QM :status: valid :belongs_to: comp__iav_primula @@ -94,7 +94,7 @@ Dynamic Architecture .. comp_arc_dyn:: IAV Primula Dynamic View :id: comp_arc_dyn__iav_primula__dv - :security: NO + :security: YES :safety: QM :status: valid :belongs_to: comp__iav_primula diff --git a/score/iav_primula/docs/component_classification.rst b/score/iav_primula/docs/component_classification.rst index 7764d4998..397cd5100 100644 --- a/score/iav_primula/docs/component_classification.rst +++ b/score/iav_primula/docs/component_classification.rst @@ -21,7 +21,7 @@ Component Classification :id: doc__iav_primula_comp_class :status: draft :safety: QM - :security: NO + :security: YES :realizes: wp__sw_component_class :tags: iav_primula diff --git a/score/iav_primula/docs/detailed_design/chklst_impl_inspection.rst b/score/iav_primula/docs/detailed_design/chklst_impl_inspection.rst index 208753ee4..af6b1f850 100644 --- a/score/iav_primula/docs/detailed_design/chklst_impl_inspection.rst +++ b/score/iav_primula/docs/detailed_design/chklst_impl_inspection.rst @@ -16,7 +16,7 @@ :id: doc__iav_primula_impl_inspection :status: draft :safety: QM - :security: NO + :security: YES :realizes: wp__sw_implementation_inspection :tags: iav_primula diff --git a/score/iav_primula/docs/detailed_design/detailed_design_example.rst b/score/iav_primula/docs/detailed_design/detailed_design_example.rst index a65c77ebe..0c3e52a0b 100644 --- a/score/iav_primula/docs/detailed_design/detailed_design_example.rst +++ b/score/iav_primula/docs/detailed_design/detailed_design_example.rst @@ -19,7 +19,7 @@ IAV Primula Detailed Design :id: doc__iav_primula_detailed_design :status: draft :safety: QM - :security: NO + :security: YES :realizes: wp__sw_implementation :tags: iav_primula @@ -29,7 +29,7 @@ Detailed Design for Component: IAV Primula Description ----------- -The implementation is intentionally small and centralized in ``src/lib.rs``. +The implementation is intentionally small and centralized in ``src/main.rs``. Design constraints: @@ -39,7 +39,7 @@ Design constraints: Current unit split: -- ``src/lib.rs``: public API and implementation of ``get_hello_message()``. +- ``src/main.rs``: public API and implementation of ``get_hello_message()``. Rationale Behind Decomposition into Units ****************************************** @@ -84,4 +84,4 @@ API headers, trait definitions, or documented function signatures). Current unit list: -- ``lib.rs``: returns constant hello message string. +- ``main.rs``: returns constant hello message string. diff --git a/score/iav_primula/docs/index.rst b/score/iav_primula/docs/index.rst index 68fdc6c8b..14d105ce9 100644 --- a/score/iav_primula/docs/index.rst +++ b/score/iav_primula/docs/index.rst @@ -23,7 +23,7 @@ IAV Primula Component :id: doc__iav_primula :status: draft :safety: QM - :security: NO + :security: YES :realizes: wp__cmpt_request :tags: iav_primula diff --git a/score/iav_primula/docs/requirements/chklst_req_inspection.rst b/score/iav_primula/docs/requirements/chklst_req_inspection.rst index 140691383..04555aed5 100644 --- a/score/iav_primula/docs/requirements/chklst_req_inspection.rst +++ b/score/iav_primula/docs/requirements/chklst_req_inspection.rst @@ -17,7 +17,7 @@ :id: doc__iav_primula_req_inspection :status: draft :safety: QM - :security: NO + :security: YES :realizes: wp__requirements_inspect :tags: iav_primula diff --git a/score/iav_primula/docs/requirements/requirements.rst b/score/iav_primula/docs/requirements/requirements.rst index 5ca8e7205..535ce2e3b 100644 --- a/score/iav_primula/docs/requirements/requirements.rst +++ b/score/iav_primula/docs/requirements/requirements.rst @@ -19,7 +19,7 @@ IAV Primula Requirements :id: doc__iav_primula_requirements :status: draft :safety: QM - :security: NO + :security: YES :realizes: wp__requirements_comp[version==1] :tags: iav_primula @@ -50,7 +50,7 @@ Assumption of Use Requirements .. aou_req:: Integrate as Rust library API :id: aou_req__iav_primula__rust_lib_api :reqtype: Process - :security: NO + :security: YES :safety: QM :status: valid @@ -63,7 +63,7 @@ Environmental Requirements .. aou_req:: Build environment supports Rust 2021 :id: aou_req__iav_primula__rust2021_build_env :reqtype: Process - :security: NO + :security: YES :safety: QM :status: valid :tags: environment diff --git a/score/iav_primula/docs/safety_analysis/aou_requirements_template.rst b/score/iav_primula/docs/safety_analysis/aou_requirements_template.rst index 054dbea1b..d8409be41 100644 --- a/score/iav_primula/docs/safety_analysis/aou_requirements_template.rst +++ b/score/iav_primula/docs/safety_analysis/aou_requirements_template.rst @@ -25,7 +25,7 @@ Component AoU .. aou_req:: Integrate as Rust library API :id: aou_req__iav_primula__integrate_as_rust_library_api :reqtype: Process - :security: NO + :security: YES :safety: QM :status: valid @@ -34,7 +34,7 @@ Component AoU .. aou_req:: Build environment supports Rust 2021 :id: aou_req__iav_primula__build_env_supports_rust_2021 :reqtype: Process - :security: NO + :security: YES :safety: QM :status: valid :tags: environment diff --git a/score/iav_primula/docs/safety_analysis/dfa.rst b/score/iav_primula/docs/safety_analysis/dfa.rst index 0cd1f02e9..168b2e6b7 100644 --- a/score/iav_primula/docs/safety_analysis/dfa.rst +++ b/score/iav_primula/docs/safety_analysis/dfa.rst @@ -20,7 +20,7 @@ DFA (Dependent Failure Analysis) :id: doc__iav_primula_dfa :status: draft :safety: QM - :security: NO + :security: YES :realizes: wp__sw_component_dfa :tags: iav_primula diff --git a/score/iav_primula/docs/safety_analysis/fmea.rst b/score/iav_primula/docs/safety_analysis/fmea.rst index dad997f63..6d203646f 100644 --- a/score/iav_primula/docs/safety_analysis/fmea.rst +++ b/score/iav_primula/docs/safety_analysis/fmea.rst @@ -20,7 +20,7 @@ FMEA (Failure Modes and Effects Analysis) :id: doc__iav_primula_fmea :status: draft :safety: QM - :security: NO + :security: YES :realizes: wp__sw_component_fmea :tags: iav_primula From d1904ded360d7c02c99e287d151434fe548b08e8 Mon Sep 17 00:00:00 2001 From: HeHa112 <113408507+HeHa112@users.noreply.github.com> Date: Thu, 20 Aug 2026 12:30:26 +0200 Subject: [PATCH 07/12] Fix "PR Checks" action (#4) --- MODULE.bazel.lock | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index d4d9dcc5f..a7bb39ddc 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1538,33 +1538,6 @@ "recordedRepoMappingEntries": [] } }, - "@@pybind11_bazel+//:internal_configure.bzl%internal_configure_extension": { - "general": { - "bzlTransitiveDigest": "doxdX2drQaP4mqY6tnLSIGABgYuXR5Hpp6Wpfyb23Rg=", - "usagesDigest": "tVQNvLoXMWAbiK39am3yovKGpwINdftfn7RpDyN+JZc=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, - "generatedRepoSpecs": { - "pybind11": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "build_file": "@@pybind11_bazel+//:pybind11-BUILD.bazel", - "strip_prefix": "pybind11-2.13.6", - "url": "https://github.com/pybind/pybind11/archive/refs/tags/v2.13.6.tar.gz", - "integrity": "sha256-4Iy4f0dz2pf6e18DXeh2OrxlbYfVdz5i9toFh9Hw7CA=" - } - } - }, - "recordedRepoMappingEntries": [ - [ - "pybind11_bazel+", - "bazel_tools", - "bazel_tools" - ] - ] - } - }, "@@rules_buf+//buf:extensions.bzl%buf": { "general": { "bzlTransitiveDigest": "dSWqckK2ILN7aDIDHfv+Qrl1fb1hF7o7MDXY6T8C41s=", From 207f64a443bec83407a44315022df3cd533ba60b Mon Sep 17 00:00:00 2001 From: "Henrik Hansen (IAV)" Date: Tue, 25 Aug 2026 12:01:05 +0200 Subject: [PATCH 08/12] iav_primula: bazel lockfile update --- MODULE.bazel.lock | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 13ef0c1d7..3350fe53d 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1251,22 +1251,29 @@ }, "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "general": { - "bzlTransitiveDigest": "cl5A2O84vDL6Tt+Qga8FCj1DUDGqn+e7ly5rZ+4xvcc=", - "usagesDigest": "YrfZ4bJpm8TElVj7Cl9MuPxrvXtxG3i75iLf1pGcdG8=", + "bzlTransitiveDigest": "XVKR7Fz0TpsBTBIjxfUrpsRKdh9a5XZHQEJmfRGJOD8=", + "usagesDigest": "4eYfYGZkkZZem5Ss/tvRTn4oYAhl3RAUYpmiLLQszC0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, - "envVariables": {}, + "envVariables": { + "ASPECT_TOOLS_TELEMETRY_TEST": null + }, "generatedRepoSpecs": { "aspect_tools_telemetry_report": { "repoRuleId": "@@aspect_tools_telemetry+//:extension.bzl%tel_repository", "attributes": { "deps": { - "aspect_rules_lint": "2.7.2", - "aspect_tools_telemetry": "0.3.3" - } + "aspect_rules_lint": "2.8.0", + "aspect_tools_telemetry": "0.5.0" + }, + "last_notice": 2 } } }, + "moduleExtensionMetadata": { + "useAllRepos": "NO", + "reproducible": false + }, "recordedRepoMappingEntries": [ [ "aspect_tools_telemetry+", @@ -2511,5 +2518,9 @@ } } }, - "facts": {} + "facts": { + "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { + "notice_version": "2" + } + } } From 64e9e2e57e20a1ee20a0c1538c513d1b0b175431 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Aug 2026 09:02:18 +0000 Subject: [PATCH 09/12] Bump openssl from 0.10.68 to 0.10.80 in /score/cryptoki Bumps [openssl](https://github.com/rust-openssl/rust-openssl) from 0.10.68 to 0.10.80. - [Release notes](https://github.com/rust-openssl/rust-openssl/releases) - [Commits](https://github.com/rust-openssl/rust-openssl/compare/openssl-v0.10.68...openssl-v0.10.80) --- updated-dependencies: - dependency-name: openssl dependency-version: 0.10.80 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- score/cryptoki/Cargo.lock | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/score/cryptoki/Cargo.lock b/score/cryptoki/Cargo.lock index c89cbfd69..f873c9b5a 100644 --- a/score/cryptoki/Cargo.lock +++ b/score/cryptoki/Cargo.lock @@ -633,15 +633,14 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "openssl" -version = "0.10.68" +version = "0.10.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" dependencies = [ "bitflags", "cfg-if", "foreign-types", "libc", - "once_cell", "openssl-macros", "openssl-sys", ] From ddb318a8beb06726353a5c056b4ce902da74424e Mon Sep 17 00:00:00 2001 From: "Henrik Hansen (IAV)" Date: Tue, 1 Sep 2026 14:20:04 +0200 Subject: [PATCH 10/12] iav_primula: update MODULE.bazel.lock --- MODULE.bazel.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index e35f09d9f..31d36a29f 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -8500,7 +8500,7 @@ "bzlTransitiveDigest": "dVzUYZOMCmY4S/2o7jFmWXqRvZ9gTYlmjacTOfwzCh4=", "usagesDigest": "Ze9h0U0ZkpTbTWuxhjsLol+EDFknrBAMj8LM8KIdJNA=", "recordedFileInputs": { - "@@//score/cryptoki/Cargo.lock": "2c53826b0b1590d9a00c4189f812b3a3cd98d3124450e4c3363bdc87db73ca0e", + "@@//score/cryptoki/Cargo.lock": "ac208f5b8efdce599a051c15eca72499dfe596fdc1e20afb5ef1ef44c4f8da80", "@@//score/cryptoki/Cargo.toml": "b2981096af4f28666df7e229de67ecfcbda89c9f24c200c1dc46c49982d25fcc" }, "recordedDirentsInputs": {}, @@ -8519,9 +8519,9 @@ "repoRuleId": "@@rules_rust+//crate_universe:extensions.bzl%_generate_repo", "attributes": { "contents": { - "BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files(\n [\n \"cargo-bazel.json\",\n \"crates.bzl\",\n \"defs.bzl\",\n ] + glob(\n allow_empty = True,\n include = [\"*.bazel\"],\n ),\n)\n\nfilegroup(\n name = \"srcs\",\n srcs = glob(\n allow_empty = True,\n include = [\n \"*.bazel\",\n \"*.bzl\",\n ],\n ),\n)\n\n# Workspace Member Dependencies\nalias(\n name = \"argon2-0.5.3\",\n actual = \"@crates__argon2-0.5.3//:argon2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"argon2\",\n actual = \"@crates__argon2-0.5.3//:argon2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dirs-5.0.1\",\n actual = \"@crates__dirs-5.0.1//:dirs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dirs\",\n actual = \"@crates__dirs-5.0.1//:dirs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libc-0.2.186\",\n actual = \"@crates__libc-0.2.186//:libc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libc\",\n actual = \"@crates__libc-0.2.186//:libc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"once_cell-1.21.4\",\n actual = \"@crates__once_cell-1.21.4//:once_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"once_cell\",\n actual = \"@crates__once_cell-1.21.4//:once_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"openssl-0.10.68\",\n actual = \"@crates__openssl-0.10.68//:openssl\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"openssl\",\n actual = \"@crates__openssl-0.10.68//:openssl\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parking_lot-0.12.5\",\n actual = \"@crates__parking_lot-0.12.5//:parking_lot\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parking_lot\",\n actual = \"@crates__parking_lot-0.12.5//:parking_lot\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parsec-client-0.16.0\",\n actual = \"@crates__parsec-client-0.16.0//:parsec_client\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parsec-client\",\n actual = \"@crates__parsec-client-0.16.0//:parsec_client\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde-1.0.228\",\n actual = \"@crates__serde-1.0.228//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde\",\n actual = \"@crates__serde-1.0.228//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json-1.0.150\",\n actual = \"@crates__serde_json-1.0.150//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json\",\n actual = \"@crates__serde_json-1.0.150//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serial_test-3.5.0\",\n actual = \"@crates__serial_test-3.5.0//:serial_test\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serial_test\",\n actual = \"@crates__serial_test-3.5.0//:serial_test\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tempfile-3.27.0\",\n actual = \"@crates__tempfile-3.27.0//:tempfile\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tempfile\",\n actual = \"@crates__tempfile-3.27.0//:tempfile\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"toml-0.8.19\",\n actual = \"@crates__toml-0.8.19//:toml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"toml\",\n actual = \"@crates__toml-0.8.19//:toml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"zeroize-1.8.2\",\n actual = \"@crates__zeroize-1.8.2//:zeroize\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"zeroize\",\n actual = \"@crates__zeroize-1.8.2//:zeroize\",\n tags = [\"manual\"],\n)\n", + "BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files(\n [\n \"cargo-bazel.json\",\n \"crates.bzl\",\n \"defs.bzl\",\n ] + glob(\n allow_empty = True,\n include = [\"*.bazel\"],\n ),\n)\n\nfilegroup(\n name = \"srcs\",\n srcs = glob(\n allow_empty = True,\n include = [\n \"*.bazel\",\n \"*.bzl\",\n ],\n ),\n)\n\n# Workspace Member Dependencies\nalias(\n name = \"argon2-0.5.3\",\n actual = \"@crates__argon2-0.5.3//:argon2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"argon2\",\n actual = \"@crates__argon2-0.5.3//:argon2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dirs-5.0.1\",\n actual = \"@crates__dirs-5.0.1//:dirs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dirs\",\n actual = \"@crates__dirs-5.0.1//:dirs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libc-0.2.186\",\n actual = \"@crates__libc-0.2.186//:libc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libc\",\n actual = \"@crates__libc-0.2.186//:libc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"once_cell-1.21.4\",\n actual = \"@crates__once_cell-1.21.4//:once_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"once_cell\",\n actual = \"@crates__once_cell-1.21.4//:once_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"openssl-0.10.80\",\n actual = \"@crates__openssl-0.10.80//:openssl\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"openssl\",\n actual = \"@crates__openssl-0.10.80//:openssl\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parking_lot-0.12.5\",\n actual = \"@crates__parking_lot-0.12.5//:parking_lot\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parking_lot\",\n actual = \"@crates__parking_lot-0.12.5//:parking_lot\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parsec-client-0.16.0\",\n actual = \"@crates__parsec-client-0.16.0//:parsec_client\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parsec-client\",\n actual = \"@crates__parsec-client-0.16.0//:parsec_client\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde-1.0.228\",\n actual = \"@crates__serde-1.0.228//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde\",\n actual = \"@crates__serde-1.0.228//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json-1.0.150\",\n actual = \"@crates__serde_json-1.0.150//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json\",\n actual = \"@crates__serde_json-1.0.150//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serial_test-3.5.0\",\n actual = \"@crates__serial_test-3.5.0//:serial_test\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serial_test\",\n actual = \"@crates__serial_test-3.5.0//:serial_test\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tempfile-3.27.0\",\n actual = \"@crates__tempfile-3.27.0//:tempfile\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tempfile\",\n actual = \"@crates__tempfile-3.27.0//:tempfile\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"toml-0.8.19\",\n actual = \"@crates__toml-0.8.19//:toml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"toml\",\n actual = \"@crates__toml-0.8.19//:toml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"zeroize-1.8.2\",\n actual = \"@crates__zeroize-1.8.2//:zeroize\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"zeroize\",\n actual = \"@crates__zeroize-1.8.2//:zeroize\",\n tags = [\"manual\"],\n)\n", "alias_rules.bzl": "\"\"\"Alias that transitions its target to `compilation_mode=opt`. Use `transition_alias=\"opt\"` to enable.\"\"\"\n\nload(\"@rules_cc//cc:defs.bzl\", \"CcInfo\")\nload(\"@rules_rust//rust:rust_common.bzl\", \"COMMON_PROVIDERS\")\n\ndef _transition_alias_impl(ctx):\n # `ctx.attr.actual` is a list of 1 item due to the transition\n providers = [ctx.attr.actual[0][provider] for provider in COMMON_PROVIDERS]\n if CcInfo in ctx.attr.actual[0]:\n providers.append(ctx.attr.actual[0][CcInfo])\n return providers\n\ndef _change_compilation_mode(compilation_mode):\n def _change_compilation_mode_impl(_settings, _attr):\n return {\n \"//command_line_option:compilation_mode\": compilation_mode,\n }\n\n return transition(\n implementation = _change_compilation_mode_impl,\n inputs = [],\n outputs = [\n \"//command_line_option:compilation_mode\",\n ],\n )\n\ndef _transition_alias_rule(compilation_mode):\n return rule(\n implementation = _transition_alias_impl,\n provides = COMMON_PROVIDERS,\n attrs = {\n \"actual\": attr.label(\n mandatory = True,\n doc = \"`rust_library()` target to transition to `compilation_mode=opt`.\",\n providers = COMMON_PROVIDERS,\n cfg = _change_compilation_mode(compilation_mode),\n ),\n \"_allowlist_function_transition\": attr.label(\n default = \"@bazel_tools//tools/allowlists/function_transition_allowlist\",\n ),\n },\n doc = \"Transitions a Rust library crate to the `compilation_mode=opt`.\",\n )\n\ntransition_alias_dbg = _transition_alias_rule(\"dbg\")\ntransition_alias_fastbuild = _transition_alias_rule(\"fastbuild\")\ntransition_alias_opt = _transition_alias_rule(\"opt\")\n", - "defs.bzl": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\"\"\"\n# `crates_repository` API\n\n- [aliases](#aliases)\n- [crate_deps](#crate_deps)\n- [all_crate_deps](#all_crate_deps)\n- [crate_repositories](#crate_repositories)\n\n\"\"\"\n\nload(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"new_git_repository\")\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\nload(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")\nload(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\nload(\"@rules_rust//crate_universe/private:local_crate_mirror.bzl\", \"local_crate_mirror\")\n\n###############################################################################\n# MACROS API\n###############################################################################\n\n# An identifier that represent common dependencies (unconditional).\n_COMMON_CONDITION = \"\"\n\ndef _flatten_dependency_maps(all_dependency_maps):\n \"\"\"Flatten a list of dependency maps into one dictionary.\n\n Dependency maps have the following structure:\n\n ```python\n DEPENDENCIES_MAP = {\n # The first key in the map is a Bazel package\n # name of the workspace this file is defined in.\n \"workspace_member_package\": {\n\n # Not all dependencies are supported for all platforms.\n # the condition key is the condition required to be true\n # on the host platform.\n \"condition\": {\n\n # An alias to a crate target. # The label of the crate target the\n # Aliases are only crate names. # package name refers to.\n \"package_name\": \"@full//:label\",\n }\n }\n }\n ```\n\n Args:\n all_dependency_maps (list): A list of dicts as described above\n\n Returns:\n dict: A dictionary as described above\n \"\"\"\n dependencies = {}\n\n for workspace_deps_map in all_dependency_maps:\n for pkg_name, conditional_deps_map in workspace_deps_map.items():\n if pkg_name not in dependencies:\n non_frozen_map = dict()\n for key, values in conditional_deps_map.items():\n non_frozen_map.update({key: dict(values.items())})\n dependencies.setdefault(pkg_name, non_frozen_map)\n continue\n\n for condition, deps_map in conditional_deps_map.items():\n # If the condition has not been recorded, do so and continue\n if condition not in dependencies[pkg_name]:\n dependencies[pkg_name].setdefault(condition, dict(deps_map.items()))\n continue\n\n # Alert on any miss-matched dependencies\n inconsistent_entries = []\n for crate_name, crate_label in deps_map.items():\n existing = dependencies[pkg_name][condition].get(crate_name)\n if existing and existing != crate_label:\n inconsistent_entries.append((crate_name, existing, crate_label))\n dependencies[pkg_name][condition].update({crate_name: crate_label})\n\n return dependencies\n\ndef crate_deps(deps, package_name = None):\n \"\"\"Finds the fully qualified label of the requested crates for the package where this macro is called.\n\n Args:\n deps (list): The desired list of crate targets.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()`.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if not deps:\n return []\n\n if package_name == None:\n package_name = native.package_name()\n\n # Join both sets of dependencies\n dependencies = _flatten_dependency_maps([\n _NORMAL_DEPENDENCIES,\n _NORMAL_DEV_DEPENDENCIES,\n _PROC_MACRO_DEPENDENCIES,\n _PROC_MACRO_DEV_DEPENDENCIES,\n _BUILD_DEPENDENCIES,\n _BUILD_PROC_MACRO_DEPENDENCIES,\n ]).pop(package_name, {})\n\n # Combine all conditional packages so we can easily index over a flat list\n # TODO: Perhaps this should actually return select statements and maintain\n # the conditionals of the dependencies\n flat_deps = {}\n for deps_set in dependencies.values():\n for crate_name, crate_label in deps_set.items():\n flat_deps.update({crate_name: crate_label})\n\n missing_crates = []\n crate_targets = []\n for crate_target in deps:\n if crate_target not in flat_deps:\n missing_crates.append(crate_target)\n else:\n crate_targets.append(flat_deps[crate_target])\n\n if missing_crates:\n fail(\"Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`\".format(\n missing_crates,\n package_name,\n dependencies,\n ))\n\n return crate_targets\n\ndef all_crate_deps(\n normal = False, \n normal_dev = False, \n proc_macro = False, \n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Finds the fully qualified label of all requested direct crate dependencies \\\n for the package where this macro is called.\n\n If no parameters are set, all normal dependencies are returned. Setting any one flag will\n otherwise impact the contents of the returned list.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list.\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_dependency_maps = []\n if normal:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n if normal_dev:\n all_dependency_maps.append(_NORMAL_DEV_DEPENDENCIES)\n if proc_macro:\n all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES)\n if proc_macro_dev:\n all_dependency_maps.append(_PROC_MACRO_DEV_DEPENDENCIES)\n if build:\n all_dependency_maps.append(_BUILD_DEPENDENCIES)\n if build_proc_macro:\n all_dependency_maps.append(_BUILD_PROC_MACRO_DEPENDENCIES)\n\n # Default to always using normal dependencies\n if not all_dependency_maps:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n\n dependencies = _flatten_dependency_maps(all_dependency_maps).pop(package_name, None)\n\n if not dependencies:\n if dependencies == None:\n fail(\"Tried to get all_crate_deps for package \" + package_name + \" but that package had no Cargo.toml file\")\n else:\n return []\n\n crate_deps = list(dependencies.pop(_COMMON_CONDITION, {}).values())\n for condition, deps in dependencies.items():\n crate_deps += selects.with_or({\n tuple(_CONDITIONS[condition]): deps.values(),\n \"//conditions:default\": [],\n })\n\n return crate_deps\n\ndef aliases(\n normal = False,\n normal_dev = False,\n proc_macro = False,\n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Produces a map of Crate alias names to their original label\n\n If no dependency kinds are specified, `normal` and `proc_macro` are used by default.\n Setting any one flag will otherwise determine the contents of the returned dict.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list..\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n dict: The aliases of all associated packages\n \"\"\"\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_aliases_maps = []\n if normal:\n all_aliases_maps.append(_NORMAL_ALIASES)\n if normal_dev:\n all_aliases_maps.append(_NORMAL_DEV_ALIASES)\n if proc_macro:\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n if proc_macro_dev:\n all_aliases_maps.append(_PROC_MACRO_DEV_ALIASES)\n if build:\n all_aliases_maps.append(_BUILD_ALIASES)\n if build_proc_macro:\n all_aliases_maps.append(_BUILD_PROC_MACRO_ALIASES)\n\n # Default to always using normal aliases\n if not all_aliases_maps:\n all_aliases_maps.append(_NORMAL_ALIASES)\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n\n aliases = _flatten_dependency_maps(all_aliases_maps).pop(package_name, None)\n\n if not aliases:\n return dict()\n\n common_items = aliases.pop(_COMMON_CONDITION, {}).items()\n\n # If there are only common items in the dictionary, immediately return them\n if not len(aliases.keys()) == 1:\n return dict(common_items)\n\n # Build a single select statement where each conditional has accounted for the\n # common set of aliases.\n crate_aliases = {\"//conditions:default\": dict(common_items)}\n for condition, deps in aliases.items():\n condition_triples = _CONDITIONS[condition]\n for triple in condition_triples:\n if triple in crate_aliases:\n crate_aliases[triple].update(deps)\n else:\n crate_aliases.update({triple: dict(deps.items() + common_items)})\n\n return select(crate_aliases)\n\n###############################################################################\n# WORKSPACE MEMBER DEPS AND ALIASES\n###############################################################################\n\n_NORMAL_DEPENDENCIES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n \"argon2\": Label(\"@crates//:argon2-0.5.3\"),\n \"dirs\": Label(\"@crates//:dirs-5.0.1\"),\n \"libc\": Label(\"@crates//:libc-0.2.186\"),\n \"once_cell\": Label(\"@crates//:once_cell-1.21.4\"),\n \"openssl\": Label(\"@crates//:openssl-0.10.68\"),\n \"parking_lot\": Label(\"@crates//:parking_lot-0.12.5\"),\n \"parsec-client\": Label(\"@crates//:parsec-client-0.16.0\"),\n \"serde\": Label(\"@crates//:serde-1.0.228\"),\n \"serde_json\": Label(\"@crates//:serde_json-1.0.150\"),\n \"tempfile\": Label(\"@crates//:tempfile-3.27.0\"),\n \"toml\": Label(\"@crates//:toml-0.8.19\"),\n \"zeroize\": Label(\"@crates//:zeroize-1.8.2\"),\n },\n },\n}\n\n\n_NORMAL_ALIASES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_NORMAL_DEV_DEPENDENCIES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n \"serial_test\": Label(\"@crates//:serial_test-3.5.0\"),\n },\n },\n}\n\n\n_NORMAL_DEV_ALIASES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_PROC_MACRO_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_PROC_MACRO_ALIASES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_PROC_MACRO_DEV_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_PROC_MACRO_DEV_ALIASES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_BUILD_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_BUILD_ALIASES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_ALIASES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_CONDITIONS = {\n \"aarch64-linux-android\": [],\n \"aarch64-pc-windows-gnullvm\": [],\n \"aarch64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\"],\n \"aarch64-unknown-nto-qnx800\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\"],\n \"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [],\n \"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), not(any(all(target_os = \\\"linux\\\", target_env = \\\"\\\"), getrandom_backend = \\\"custom\\\", getrandom_backend = \\\"linux_raw\\\", getrandom_backend = \\\"rdrand\\\", getrandom_backend = \\\"rndr\\\"))))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\"],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_os = \\\"linux\\\"))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\"],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_vendor = \\\"apple\\\"))\": [],\n \"cfg(all(target_arch = \\\"loongarch64\\\", target_os = \\\"linux\\\"))\": [],\n \"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"wasi\\\", target_env = \\\"p2\\\"))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"gnu\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86_64\\\", target_env = \\\"gnu\\\", not(target_abi = \\\"llvm\\\"), not(windows_raw_dylib)))\": [\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(all(target_arch = \\\"x86_64\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_os = \\\"uefi\\\", getrandom_backend = \\\"efi_rng\\\"))\": [],\n \"cfg(any())\": [],\n \"cfg(any(target_arch = \\\"x86\\\", target_arch = \\\"x86_64\\\"))\": [\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(any(target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"hurd\\\", target_os = \\\"illumos\\\", target_os = \\\"cygwin\\\", all(target_os = \\\"horizon\\\", target_arch = \\\"arm\\\")))\": [],\n \"cfg(any(target_os = \\\"haiku\\\", target_os = \\\"redox\\\", target_os = \\\"nto\\\", target_os = \\\"aix\\\"))\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\"],\n \"cfg(any(target_os = \\\"ios\\\", target_os = \\\"visionos\\\", target_os = \\\"watchos\\\", target_os = \\\"tvos\\\"))\": [],\n \"cfg(any(target_os = \\\"macos\\\", target_os = \\\"openbsd\\\", target_os = \\\"vita\\\", target_os = \\\"emscripten\\\"))\": [],\n \"cfg(any(unix, target_os = \\\"wasi\\\"))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(target_os = \\\"hermit\\\")\": [],\n \"cfg(target_os = \\\"netbsd\\\")\": [],\n \"cfg(target_os = \\\"redox\\\")\": [],\n \"cfg(target_os = \\\"solaris\\\")\": [],\n \"cfg(target_os = \\\"vxworks\\\")\": [],\n \"cfg(target_os = \\\"wasi\\\")\": [],\n \"cfg(unix)\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(windows)\": [],\n \"x86_64-pc-nto-qnx800\": [\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\"],\n \"x86_64-pc-windows-gnullvm\": [],\n \"x86_64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n}\n\n###############################################################################\n\ndef crate_repositories():\n \"\"\"A macro for defining repositories for all generated crates.\n\n Returns:\n A list of repos visible to the module through the module extension.\n \"\"\"\n maybe(\n http_archive,\n name = \"crates__aho-corasick-1.1.4\",\n sha256 = \"ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aho-corasick/1.1.4/download\"],\n strip_prefix = \"aho-corasick-1.1.4\",\n build_file = Label(\"@crates//crates:BUILD.aho-corasick-1.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anyhow-1.0.102\",\n sha256 = \"7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anyhow/1.0.102/download\"],\n strip_prefix = \"anyhow-1.0.102\",\n build_file = Label(\"@crates//crates:BUILD.anyhow-1.0.102.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__argon2-0.5.3\",\n sha256 = \"3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/argon2/0.5.3/download\"],\n strip_prefix = \"argon2-0.5.3\",\n build_file = Label(\"@crates//crates:BUILD.argon2-0.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__autocfg-1.5.1\",\n sha256 = \"f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/autocfg/1.5.1/download\"],\n strip_prefix = \"autocfg-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.autocfg-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__base64ct-1.6.0\",\n sha256 = \"8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/base64ct/1.6.0/download\"],\n strip_prefix = \"base64ct-1.6.0\",\n build_file = Label(\"@crates//crates:BUILD.base64ct-1.6.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bincode-1.3.3\",\n sha256 = \"b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bincode/1.3.3/download\"],\n strip_prefix = \"bincode-1.3.3\",\n build_file = Label(\"@crates//crates:BUILD.bincode-1.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bitflags-2.11.1\",\n sha256 = \"c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bitflags/2.11.1/download\"],\n strip_prefix = \"bitflags-2.11.1\",\n build_file = Label(\"@crates//crates:BUILD.bitflags-2.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__blake2-0.10.6\",\n sha256 = \"46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/blake2/0.10.6/download\"],\n strip_prefix = \"blake2-0.10.6\",\n build_file = Label(\"@crates//crates:BUILD.blake2-0.10.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__block-buffer-0.10.4\",\n sha256 = \"3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/block-buffer/0.10.4/download\"],\n strip_prefix = \"block-buffer-0.10.4\",\n build_file = Label(\"@crates//crates:BUILD.block-buffer-0.10.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytes-1.11.1\",\n sha256 = \"1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytes/1.11.1/download\"],\n strip_prefix = \"bytes-1.11.1\",\n build_file = Label(\"@crates//crates:BUILD.bytes-1.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cc-1.2.63\",\n sha256 = \"556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cc/1.2.63/download\"],\n strip_prefix = \"cc-1.2.63\",\n build_file = Label(\"@crates//crates:BUILD.cc-1.2.63.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg-if-1.0.4\",\n sha256 = \"9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg-if/1.0.4/download\"],\n strip_prefix = \"cfg-if-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.cfg-if-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cmake-0.1.58\",\n sha256 = \"c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cmake/0.1.58/download\"],\n strip_prefix = \"cmake-0.1.58\",\n build_file = Label(\"@crates//crates:BUILD.cmake-0.1.58.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cpufeatures-0.2.17\",\n sha256 = \"59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cpufeatures/0.2.17/download\"],\n strip_prefix = \"cpufeatures-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.cpufeatures-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crypto-common-0.1.7\",\n sha256 = \"78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crypto-common/0.1.7/download\"],\n strip_prefix = \"crypto-common-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.crypto-common-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__derivative-2.2.0\",\n sha256 = \"fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/derivative/2.2.0/download\"],\n strip_prefix = \"derivative-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.derivative-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__digest-0.10.7\",\n sha256 = \"9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/digest/0.10.7/download\"],\n strip_prefix = \"digest-0.10.7\",\n build_file = Label(\"@crates//crates:BUILD.digest-0.10.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dirs-5.0.1\",\n sha256 = \"44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dirs/5.0.1/download\"],\n strip_prefix = \"dirs-5.0.1\",\n build_file = Label(\"@crates//crates:BUILD.dirs-5.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dirs-sys-0.4.1\",\n sha256 = \"520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dirs-sys/0.4.1/download\"],\n strip_prefix = \"dirs-sys-0.4.1\",\n build_file = Label(\"@crates//crates:BUILD.dirs-sys-0.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__displaydoc-0.2.6\",\n sha256 = \"1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/displaydoc/0.2.6/download\"],\n strip_prefix = \"displaydoc-0.2.6\",\n build_file = Label(\"@crates//crates:BUILD.displaydoc-0.2.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__either-1.16.0\",\n sha256 = \"91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/either/1.16.0/download\"],\n strip_prefix = \"either-1.16.0\",\n build_file = Label(\"@crates//crates:BUILD.either-1.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__equivalent-1.0.2\",\n sha256 = \"877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/equivalent/1.0.2/download\"],\n strip_prefix = \"equivalent-1.0.2\",\n build_file = Label(\"@crates//crates:BUILD.equivalent-1.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__errno-0.3.14\",\n sha256 = \"39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/errno/0.3.14/download\"],\n strip_prefix = \"errno-0.3.14\",\n build_file = Label(\"@crates//crates:BUILD.errno-0.3.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fastrand-2.4.1\",\n sha256 = \"9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fastrand/2.4.1/download\"],\n strip_prefix = \"fastrand-2.4.1\",\n build_file = Label(\"@crates//crates:BUILD.fastrand-2.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__find-msvc-tools-0.1.9\",\n sha256 = \"5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/find-msvc-tools/0.1.9/download\"],\n strip_prefix = \"find-msvc-tools-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.find-msvc-tools-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-0.3.2\",\n sha256 = \"f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types/0.3.2/download\"],\n strip_prefix = \"foreign-types-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-shared-0.1.1\",\n sha256 = \"00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types-shared/0.1.1/download\"],\n strip_prefix = \"foreign-types-shared-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-shared-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__form_urlencoded-1.2.2\",\n sha256 = \"cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/form_urlencoded/1.2.2/download\"],\n strip_prefix = \"form_urlencoded-1.2.2\",\n build_file = Label(\"@crates//crates:BUILD.form_urlencoded-1.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-core-0.3.32\",\n sha256 = \"7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-core/0.3.32/download\"],\n strip_prefix = \"futures-core-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-core-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-executor-0.3.32\",\n sha256 = \"baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-executor/0.3.32/download\"],\n strip_prefix = \"futures-executor-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-executor-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-task-0.3.32\",\n sha256 = \"037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-task/0.3.32/download\"],\n strip_prefix = \"futures-task-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-task-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-util-0.3.32\",\n sha256 = \"389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-util/0.3.32/download\"],\n strip_prefix = \"futures-util-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-util-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__generic-array-0.14.7\",\n sha256 = \"85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/generic-array/0.14.7/download\"],\n strip_prefix = \"generic-array-0.14.7\",\n build_file = Label(\"@crates//crates:BUILD.generic-array-0.14.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.2.17\",\n sha256 = \"ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.2.17/download\"],\n strip_prefix = \"getrandom-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.3.4\",\n sha256 = \"899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.3.4/download\"],\n strip_prefix = \"getrandom-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.14.5\",\n sha256 = \"e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.14.5/download\"],\n strip_prefix = \"hashbrown-0.14.5\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.14.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_collections-1.5.0\",\n sha256 = \"db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_collections/1.5.0/download\"],\n strip_prefix = \"icu_collections-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_collections-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locid-1.5.0\",\n sha256 = \"13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locid/1.5.0/download\"],\n strip_prefix = \"icu_locid-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locid-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locid_transform-1.5.0\",\n sha256 = \"01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locid_transform/1.5.0/download\"],\n strip_prefix = \"icu_locid_transform-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locid_transform-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locid_transform_data-1.5.1\",\n sha256 = \"7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locid_transform_data/1.5.1/download\"],\n strip_prefix = \"icu_locid_transform_data-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_locid_transform_data-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_normalizer-1.5.0\",\n sha256 = \"19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_normalizer/1.5.0/download\"],\n strip_prefix = \"icu_normalizer-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_normalizer-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_normalizer_data-1.5.1\",\n sha256 = \"c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_normalizer_data/1.5.1/download\"],\n strip_prefix = \"icu_normalizer_data-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_normalizer_data-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_properties-1.5.1\",\n sha256 = \"93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_properties/1.5.1/download\"],\n strip_prefix = \"icu_properties-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_properties-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_properties_data-1.5.1\",\n sha256 = \"85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_properties_data/1.5.1/download\"],\n strip_prefix = \"icu_properties_data-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_properties_data-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_provider-1.5.0\",\n sha256 = \"6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_provider/1.5.0/download\"],\n strip_prefix = \"icu_provider-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_provider-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_provider_macros-1.5.0\",\n sha256 = \"1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_provider_macros/1.5.0/download\"],\n strip_prefix = \"icu_provider_macros-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_provider_macros-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__idna-1.0.3\",\n sha256 = \"686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/idna/1.0.3/download\"],\n strip_prefix = \"idna-1.0.3\",\n build_file = Label(\"@crates//crates:BUILD.idna-1.0.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__idna_adapter-1.2.0\",\n sha256 = \"daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/idna_adapter/1.2.0/download\"],\n strip_prefix = \"idna_adapter-1.2.0\",\n build_file = Label(\"@crates//crates:BUILD.idna_adapter-1.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__indexmap-2.0.0\",\n sha256 = \"d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/indexmap/2.0.0/download\"],\n strip_prefix = \"indexmap-2.0.0\",\n build_file = Label(\"@crates//crates:BUILD.indexmap-2.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itertools-0.10.5\",\n sha256 = \"b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itertools/0.10.5/download\"],\n strip_prefix = \"itertools-0.10.5\",\n build_file = Label(\"@crates//crates:BUILD.itertools-0.10.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itoa-1.0.18\",\n sha256 = \"8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itoa/1.0.18/download\"],\n strip_prefix = \"itoa-1.0.18\",\n build_file = Label(\"@crates//crates:BUILD.itoa-1.0.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libc-0.2.186\",\n sha256 = \"68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libc/0.2.186/download\"],\n strip_prefix = \"libc-0.2.186\",\n build_file = Label(\"@crates//crates:BUILD.libc-0.2.186.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libredox-0.1.17\",\n sha256 = \"f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libredox/0.1.17/download\"],\n strip_prefix = \"libredox-0.1.17\",\n build_file = Label(\"@crates//crates:BUILD.libredox-0.1.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__linux-raw-sys-0.12.1\",\n sha256 = \"32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/linux-raw-sys/0.12.1/download\"],\n strip_prefix = \"linux-raw-sys-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.linux-raw-sys-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__litemap-0.7.5\",\n sha256 = \"23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/litemap/0.7.5/download\"],\n strip_prefix = \"litemap-0.7.5\",\n build_file = Label(\"@crates//crates:BUILD.litemap-0.7.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__lock_api-0.4.14\",\n sha256 = \"224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/lock_api/0.4.14/download\"],\n strip_prefix = \"lock_api-0.4.14\",\n build_file = Label(\"@crates//crates:BUILD.lock_api-0.4.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__log-0.4.30\",\n sha256 = \"616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/log/0.4.30/download\"],\n strip_prefix = \"log-0.4.30\",\n build_file = Label(\"@crates//crates:BUILD.log-0.4.30.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memchr-2.8.1\",\n sha256 = \"6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memchr/2.8.1/download\"],\n strip_prefix = \"memchr-2.8.1\",\n build_file = Label(\"@crates//crates:BUILD.memchr-2.8.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-0.4.3\",\n sha256 = \"35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num/0.4.3/download\"],\n strip_prefix = \"num-0.4.3\",\n build_file = Label(\"@crates//crates:BUILD.num-0.4.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-bigint-0.4.6\",\n sha256 = \"a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-bigint/0.4.6/download\"],\n strip_prefix = \"num-bigint-0.4.6\",\n build_file = Label(\"@crates//crates:BUILD.num-bigint-0.4.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-complex-0.4.6\",\n sha256 = \"73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-complex/0.4.6/download\"],\n strip_prefix = \"num-complex-0.4.6\",\n build_file = Label(\"@crates//crates:BUILD.num-complex-0.4.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-derive-0.4.2\",\n sha256 = \"ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-derive/0.4.2/download\"],\n strip_prefix = \"num-derive-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.num-derive-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-integer-0.1.46\",\n sha256 = \"7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-integer/0.1.46/download\"],\n strip_prefix = \"num-integer-0.1.46\",\n build_file = Label(\"@crates//crates:BUILD.num-integer-0.1.46.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-iter-0.1.45\",\n sha256 = \"1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-iter/0.1.45/download\"],\n strip_prefix = \"num-iter-0.1.45\",\n build_file = Label(\"@crates//crates:BUILD.num-iter-0.1.45.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-rational-0.4.2\",\n sha256 = \"f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-rational/0.4.2/download\"],\n strip_prefix = \"num-rational-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.num-rational-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-traits-0.2.19\",\n sha256 = \"071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-traits/0.2.19/download\"],\n strip_prefix = \"num-traits-0.2.19\",\n build_file = Label(\"@crates//crates:BUILD.num-traits-0.2.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__once_cell-1.21.4\",\n sha256 = \"9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/once_cell/1.21.4/download\"],\n strip_prefix = \"once_cell-1.21.4\",\n build_file = Label(\"@crates//crates:BUILD.once_cell-1.21.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__openssl-0.10.68\",\n sha256 = \"6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/openssl/0.10.68/download\"],\n strip_prefix = \"openssl-0.10.68\",\n build_file = Label(\"@crates//crates:BUILD.openssl-0.10.68.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__openssl-macros-0.1.1\",\n sha256 = \"a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/openssl-macros/0.1.1/download\"],\n strip_prefix = \"openssl-macros-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.openssl-macros-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__openssl-sys-0.9.116\",\n patch_args = [\n \"-p1\",\n ],\n patches = [\n \"@@//third_party/patches:openssl_sys_build_rs.patch\",\n ],\n sha256 = \"f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/openssl-sys/0.9.116/download\"],\n strip_prefix = \"openssl-sys-0.9.116\",\n build_file = Label(\"@crates//crates:BUILD.openssl-sys-0.9.116.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__option-ext-0.2.0\",\n sha256 = \"04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/option-ext/0.2.0/download\"],\n strip_prefix = \"option-ext-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.option-ext-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking_lot-0.12.5\",\n sha256 = \"93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking_lot/0.12.5/download\"],\n strip_prefix = \"parking_lot-0.12.5\",\n build_file = Label(\"@crates//crates:BUILD.parking_lot-0.12.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking_lot_core-0.9.12\",\n sha256 = \"2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking_lot_core/0.9.12/download\"],\n strip_prefix = \"parking_lot_core-0.9.12\",\n build_file = Label(\"@crates//crates:BUILD.parking_lot_core-0.9.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parsec-client-0.16.0\",\n sha256 = \"a36f9d8e27166cf0586913812454174286e094d594cc8b28d8a8d02d64406bbc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parsec-client/0.16.0/download\"],\n strip_prefix = \"parsec-client-0.16.0\",\n build_file = Label(\"@crates//crates:BUILD.parsec-client-0.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parsec-interface-0.29.1\",\n sha256 = \"cc706e09209b30f10baa35709d41b9cc01d4931b21c00679f59db96cd1650add\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parsec-interface/0.29.1/download\"],\n strip_prefix = \"parsec-interface-0.29.1\",\n build_file = Label(\"@crates//crates:BUILD.parsec-interface-0.29.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__password-hash-0.5.0\",\n sha256 = \"346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/password-hash/0.5.0/download\"],\n strip_prefix = \"password-hash-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.password-hash-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__percent-encoding-2.3.2\",\n sha256 = \"9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/percent-encoding/2.3.2/download\"],\n strip_prefix = \"percent-encoding-2.3.2\",\n build_file = Label(\"@crates//crates:BUILD.percent-encoding-2.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pin-project-lite-0.2.17\",\n sha256 = \"a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pin-project-lite/0.2.17/download\"],\n strip_prefix = \"pin-project-lite-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.pin-project-lite-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pkg-config-0.3.33\",\n sha256 = \"19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pkg-config/0.3.33/download\"],\n strip_prefix = \"pkg-config-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.pkg-config-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__proc-macro2-1.0.106\",\n sha256 = \"8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/proc-macro2/1.0.106/download\"],\n strip_prefix = \"proc-macro2-1.0.106\",\n build_file = Label(\"@crates//crates:BUILD.proc-macro2-1.0.106.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__prost-0.9.0\",\n sha256 = \"444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/prost/0.9.0/download\"],\n strip_prefix = \"prost-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.prost-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__prost-derive-0.9.0\",\n sha256 = \"f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/prost-derive/0.9.0/download\"],\n strip_prefix = \"prost-derive-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.prost-derive-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__psa-crypto-0.12.0\",\n sha256 = \"89c2256e525b9a45ec3bbb3382a43dd8809240279e0aab8ea7ee220e9295445b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/psa-crypto/0.12.0/download\"],\n strip_prefix = \"psa-crypto-0.12.0\",\n build_file = Label(\"@crates//crates:BUILD.psa-crypto-0.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__psa-crypto-sys-0.12.0\",\n sha256 = \"f170cac3a328e1678916b276067ec170a5a51db1b9b8b4c00b44c2839819a963\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/psa-crypto-sys/0.12.0/download\"],\n strip_prefix = \"psa-crypto-sys-0.12.0\",\n build_file = Label(\"@crates//crates:BUILD.psa-crypto-sys-0.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quote-1.0.45\",\n sha256 = \"41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quote/1.0.45/download\"],\n strip_prefix = \"quote-1.0.45\",\n build_file = Label(\"@crates//crates:BUILD.quote-1.0.45.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__r-efi-5.3.0\",\n sha256 = \"69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/r-efi/5.3.0/download\"],\n strip_prefix = \"r-efi-5.3.0\",\n build_file = Label(\"@crates//crates:BUILD.r-efi-5.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_core-0.6.4\",\n sha256 = \"ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_core/0.6.4/download\"],\n strip_prefix = \"rand_core-0.6.4\",\n build_file = Label(\"@crates//crates:BUILD.rand_core-0.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__redox_syscall-0.5.18\",\n sha256 = \"ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/redox_syscall/0.5.18/download\"],\n strip_prefix = \"redox_syscall-0.5.18\",\n build_file = Label(\"@crates//crates:BUILD.redox_syscall-0.5.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__redox_users-0.4.6\",\n sha256 = \"ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/redox_users/0.4.6/download\"],\n strip_prefix = \"redox_users-0.4.6\",\n build_file = Label(\"@crates//crates:BUILD.redox_users-0.4.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-1.12.3\",\n sha256 = \"e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex/1.12.3/download\"],\n strip_prefix = \"regex-1.12.3\",\n build_file = Label(\"@crates//crates:BUILD.regex-1.12.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-automata-0.4.14\",\n sha256 = \"6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-automata/0.4.14/download\"],\n strip_prefix = \"regex-automata-0.4.14\",\n build_file = Label(\"@crates//crates:BUILD.regex-automata-0.4.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-syntax-0.8.10\",\n sha256 = \"dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-syntax/0.8.10/download\"],\n strip_prefix = \"regex-syntax-0.8.10\",\n build_file = Label(\"@crates//crates:BUILD.regex-syntax-0.8.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustix-1.1.4\",\n sha256 = \"b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustix/1.1.4/download\"],\n strip_prefix = \"rustix-1.1.4\",\n build_file = Label(\"@crates//crates:BUILD.rustix-1.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__same-file-1.0.6\",\n sha256 = \"93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/same-file/1.0.6/download\"],\n strip_prefix = \"same-file-1.0.6\",\n build_file = Label(\"@crates//crates:BUILD.same-file-1.0.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__scopeguard-1.2.0\",\n sha256 = \"94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/scopeguard/1.2.0/download\"],\n strip_prefix = \"scopeguard-1.2.0\",\n build_file = Label(\"@crates//crates:BUILD.scopeguard-1.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__secrecy-0.8.0\",\n sha256 = \"9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/secrecy/0.8.0/download\"],\n strip_prefix = \"secrecy-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.secrecy-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde-1.0.228\",\n sha256 = \"9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde/1.0.228/download\"],\n strip_prefix = \"serde-1.0.228\",\n build_file = Label(\"@crates//crates:BUILD.serde-1.0.228.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_core-1.0.228\",\n sha256 = \"41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_core/1.0.228/download\"],\n strip_prefix = \"serde_core-1.0.228\",\n build_file = Label(\"@crates//crates:BUILD.serde_core-1.0.228.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_derive-1.0.228\",\n sha256 = \"d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_derive/1.0.228/download\"],\n strip_prefix = \"serde_derive-1.0.228\",\n build_file = Label(\"@crates//crates:BUILD.serde_derive-1.0.228.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_json-1.0.150\",\n sha256 = \"e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_json/1.0.150/download\"],\n strip_prefix = \"serde_json-1.0.150\",\n build_file = Label(\"@crates//crates:BUILD.serde_json-1.0.150.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_spanned-0.6.9\",\n sha256 = \"bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_spanned/0.6.9/download\"],\n strip_prefix = \"serde_spanned-0.6.9\",\n build_file = Label(\"@crates//crates:BUILD.serde_spanned-0.6.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serial_test-3.5.0\",\n sha256 = \"699f4197115b8a7e7ff19c9a315a4bd6fffec26cc4626ef45ecaea389e081c6d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serial_test/3.5.0/download\"],\n strip_prefix = \"serial_test-3.5.0\",\n build_file = Label(\"@crates//crates:BUILD.serial_test-3.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serial_test_derive-3.5.0\",\n sha256 = \"94e153fc76e1c6a068703d6d29c508a0b15c061c4b7e43da59cc097bc342673c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serial_test_derive/3.5.0/download\"],\n strip_prefix = \"serial_test_derive-3.5.0\",\n build_file = Label(\"@crates//crates:BUILD.serial_test_derive-3.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__shlex-2.0.1\",\n sha256 = \"f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/shlex/2.0.1/download\"],\n strip_prefix = \"shlex-2.0.1\",\n build_file = Label(\"@crates//crates:BUILD.shlex-2.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__slab-0.4.12\",\n sha256 = \"0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/slab/0.4.12/download\"],\n strip_prefix = \"slab-0.4.12\",\n build_file = Label(\"@crates//crates:BUILD.slab-0.4.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__smallvec-1.15.1\",\n sha256 = \"67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/smallvec/1.15.1/download\"],\n strip_prefix = \"smallvec-1.15.1\",\n build_file = Label(\"@crates//crates:BUILD.smallvec-1.15.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__stable_deref_trait-1.2.1\",\n sha256 = \"6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/stable_deref_trait/1.2.1/download\"],\n strip_prefix = \"stable_deref_trait-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.stable_deref_trait-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__subtle-2.6.1\",\n sha256 = \"13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/subtle/2.6.1/download\"],\n strip_prefix = \"subtle-2.6.1\",\n build_file = Label(\"@crates//crates:BUILD.subtle-2.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-1.0.109\",\n sha256 = \"72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/1.0.109/download\"],\n strip_prefix = \"syn-1.0.109\",\n build_file = Label(\"@crates//crates:BUILD.syn-1.0.109.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-2.0.117\",\n sha256 = \"e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/2.0.117/download\"],\n strip_prefix = \"syn-2.0.117\",\n build_file = Label(\"@crates//crates:BUILD.syn-2.0.117.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__synstructure-0.13.2\",\n sha256 = \"728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/synstructure/0.13.2/download\"],\n strip_prefix = \"synstructure-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.synstructure-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tempfile-3.27.0\",\n sha256 = \"32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tempfile/3.27.0/download\"],\n strip_prefix = \"tempfile-3.27.0\",\n build_file = Label(\"@crates//crates:BUILD.tempfile-3.27.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-1.0.69\",\n sha256 = \"b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror/1.0.69/download\"],\n strip_prefix = \"thiserror-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-impl-1.0.69\",\n sha256 = \"4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror-impl/1.0.69/download\"],\n strip_prefix = \"thiserror-impl-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-impl-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tinystr-0.7.6\",\n sha256 = \"9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tinystr/0.7.6/download\"],\n strip_prefix = \"tinystr-0.7.6\",\n build_file = Label(\"@crates//crates:BUILD.tinystr-0.7.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml-0.8.19\",\n sha256 = \"a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml/0.8.19/download\"],\n strip_prefix = \"toml-0.8.19\",\n build_file = Label(\"@crates//crates:BUILD.toml-0.8.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_datetime-0.6.11\",\n sha256 = \"22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_datetime/0.6.11/download\"],\n strip_prefix = \"toml_datetime-0.6.11\",\n build_file = Label(\"@crates//crates:BUILD.toml_datetime-0.6.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_edit-0.22.20\",\n sha256 = \"583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_edit/0.22.20/download\"],\n strip_prefix = \"toml_edit-0.22.20\",\n build_file = Label(\"@crates//crates:BUILD.toml_edit-0.22.20.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__typenum-1.20.1\",\n sha256 = \"b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/typenum/1.20.1/download\"],\n strip_prefix = \"typenum-1.20.1\",\n build_file = Label(\"@crates//crates:BUILD.typenum-1.20.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-ident-1.0.24\",\n sha256 = \"e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-ident/1.0.24/download\"],\n strip_prefix = \"unicode-ident-1.0.24\",\n build_file = Label(\"@crates//crates:BUILD.unicode-ident-1.0.24.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__url-2.5.4\",\n sha256 = \"32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/url/2.5.4/download\"],\n strip_prefix = \"url-2.5.4\",\n build_file = Label(\"@crates//crates:BUILD.url-2.5.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf16_iter-1.0.5\",\n sha256 = \"c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf16_iter/1.0.5/download\"],\n strip_prefix = \"utf16_iter-1.0.5\",\n build_file = Label(\"@crates//crates:BUILD.utf16_iter-1.0.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf8_iter-1.0.4\",\n sha256 = \"b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf8_iter/1.0.4/download\"],\n strip_prefix = \"utf8_iter-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.utf8_iter-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uuid-0.8.2\",\n sha256 = \"bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uuid/0.8.2/download\"],\n strip_prefix = \"uuid-0.8.2\",\n build_file = Label(\"@crates//crates:BUILD.uuid-0.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__vcpkg-0.2.15\",\n sha256 = \"accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/vcpkg/0.2.15/download\"],\n strip_prefix = \"vcpkg-0.2.15\",\n build_file = Label(\"@crates//crates:BUILD.vcpkg-0.2.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__version_check-0.9.5\",\n sha256 = \"0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/version_check/0.9.5/download\"],\n strip_prefix = \"version_check-0.9.5\",\n build_file = Label(\"@crates//crates:BUILD.version_check-0.9.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__walkdir-2.5.0\",\n sha256 = \"29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/walkdir/2.5.0/download\"],\n strip_prefix = \"walkdir-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.walkdir-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasi-0.11.1-wasi-snapshot-preview1\",\n sha256 = \"ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasi/0.11.1+wasi-snapshot-preview1/download\"],\n strip_prefix = \"wasi-0.11.1+wasi-snapshot-preview1\",\n build_file = Label(\"@crates//crates:BUILD.wasi-0.11.1+wasi-snapshot-preview1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasip2-1.0.3-wasi-0.2.9\",\n sha256 = \"20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasip2/1.0.3+wasi-0.2.9/download\"],\n strip_prefix = \"wasip2-1.0.3+wasi-0.2.9\",\n build_file = Label(\"@crates//crates:BUILD.wasip2-1.0.3+wasi-0.2.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-util-0.1.11\",\n sha256 = \"c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi-util/0.1.11/download\"],\n strip_prefix = \"winapi-util-0.1.11\",\n build_file = Label(\"@crates//crates:BUILD.winapi-util-0.1.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-link-0.2.1\",\n sha256 = \"f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-link/0.2.1/download\"],\n strip_prefix = \"windows-link-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-link-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.48.0\",\n sha256 = \"677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.48.0/download\"],\n strip_prefix = \"windows-sys-0.48.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.48.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.61.2\",\n sha256 = \"ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.61.2/download\"],\n strip_prefix = \"windows-sys-0.61.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.61.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-targets-0.48.5\",\n sha256 = \"9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-targets/0.48.5/download\"],\n strip_prefix = \"windows-targets-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows-targets-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_gnullvm-0.48.5\",\n sha256 = \"2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_gnullvm/0.48.5/download\"],\n strip_prefix = \"windows_aarch64_gnullvm-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_gnullvm-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_msvc-0.48.5\",\n sha256 = \"dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_msvc/0.48.5/download\"],\n strip_prefix = \"windows_aarch64_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnu-0.48.5\",\n sha256 = \"a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnu/0.48.5/download\"],\n strip_prefix = \"windows_i686_gnu-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnu-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_msvc-0.48.5\",\n sha256 = \"8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_msvc/0.48.5/download\"],\n strip_prefix = \"windows_i686_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnu-0.48.5\",\n sha256 = \"53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnu/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_gnu-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnu-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnullvm-0.48.5\",\n sha256 = \"0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnullvm/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_gnullvm-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnullvm-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_msvc-0.48.5\",\n sha256 = \"ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_msvc/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winnow-0.6.26\",\n sha256 = \"1e90edd2ac1aa278a5c4599b1d89cf03074b610800f866d4026dc199d7929a28\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winnow/0.6.26/download\"],\n strip_prefix = \"winnow-0.6.26\",\n build_file = Label(\"@crates//crates:BUILD.winnow-0.6.26.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wit-bindgen-0.57.1\",\n sha256 = \"1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wit-bindgen/0.57.1/download\"],\n strip_prefix = \"wit-bindgen-0.57.1\",\n build_file = Label(\"@crates//crates:BUILD.wit-bindgen-0.57.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__write16-1.0.0\",\n sha256 = \"d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/write16/1.0.0/download\"],\n strip_prefix = \"write16-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.write16-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__writeable-0.5.5\",\n sha256 = \"1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/writeable/0.5.5/download\"],\n strip_prefix = \"writeable-0.5.5\",\n build_file = Label(\"@crates//crates:BUILD.writeable-0.5.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yoke-0.7.5\",\n sha256 = \"120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yoke/0.7.5/download\"],\n strip_prefix = \"yoke-0.7.5\",\n build_file = Label(\"@crates//crates:BUILD.yoke-0.7.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yoke-derive-0.7.5\",\n sha256 = \"2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yoke-derive/0.7.5/download\"],\n strip_prefix = \"yoke-derive-0.7.5\",\n build_file = Label(\"@crates//crates:BUILD.yoke-derive-0.7.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerofrom-0.1.8\",\n sha256 = \"0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerofrom/0.1.8/download\"],\n strip_prefix = \"zerofrom-0.1.8\",\n build_file = Label(\"@crates//crates:BUILD.zerofrom-0.1.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerofrom-derive-0.1.7\",\n sha256 = \"11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerofrom-derive/0.1.7/download\"],\n strip_prefix = \"zerofrom-derive-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.zerofrom-derive-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zeroize-1.8.2\",\n sha256 = \"b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zeroize/1.8.2/download\"],\n strip_prefix = \"zeroize-1.8.2\",\n build_file = Label(\"@crates//crates:BUILD.zeroize-1.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zeroize_derive-1.4.3\",\n sha256 = \"85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zeroize_derive/1.4.3/download\"],\n strip_prefix = \"zeroize_derive-1.4.3\",\n build_file = Label(\"@crates//crates:BUILD.zeroize_derive-1.4.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerovec-0.10.4\",\n sha256 = \"aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerovec/0.10.4/download\"],\n strip_prefix = \"zerovec-0.10.4\",\n build_file = Label(\"@crates//crates:BUILD.zerovec-0.10.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerovec-derive-0.10.3\",\n sha256 = \"6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerovec-derive/0.10.3/download\"],\n strip_prefix = \"zerovec-derive-0.10.3\",\n build_file = Label(\"@crates//crates:BUILD.zerovec-derive-0.10.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zmij-1.0.21\",\n sha256 = \"b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zmij/1.0.21/download\"],\n strip_prefix = \"zmij-1.0.21\",\n build_file = Label(\"@crates//crates:BUILD.zmij-1.0.21.bazel\"),\n )\n\n return [\n struct(repo=\"crates__argon2-0.5.3\", is_dev_dep = False),\n struct(repo=\"crates__dirs-5.0.1\", is_dev_dep = False),\n struct(repo=\"crates__libc-0.2.186\", is_dev_dep = False),\n struct(repo=\"crates__once_cell-1.21.4\", is_dev_dep = False),\n struct(repo=\"crates__openssl-0.10.68\", is_dev_dep = False),\n struct(repo=\"crates__parking_lot-0.12.5\", is_dev_dep = False),\n struct(repo=\"crates__parsec-client-0.16.0\", is_dev_dep = False),\n struct(repo=\"crates__serde-1.0.228\", is_dev_dep = False),\n struct(repo=\"crates__serde_json-1.0.150\", is_dev_dep = False),\n struct(repo=\"crates__tempfile-3.27.0\", is_dev_dep = False),\n struct(repo=\"crates__toml-0.8.19\", is_dev_dep = False),\n struct(repo=\"crates__zeroize-1.8.2\", is_dev_dep = False),\n struct(repo = \"crates__serial_test-3.5.0\", is_dev_dep = True),\n ]\n" + "defs.bzl": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\"\"\"\n# `crates_repository` API\n\n- [aliases](#aliases)\n- [crate_deps](#crate_deps)\n- [all_crate_deps](#all_crate_deps)\n- [crate_repositories](#crate_repositories)\n\n\"\"\"\n\nload(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"new_git_repository\")\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\nload(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")\nload(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\nload(\"@rules_rust//crate_universe/private:local_crate_mirror.bzl\", \"local_crate_mirror\")\n\n###############################################################################\n# MACROS API\n###############################################################################\n\n# An identifier that represent common dependencies (unconditional).\n_COMMON_CONDITION = \"\"\n\ndef _flatten_dependency_maps(all_dependency_maps):\n \"\"\"Flatten a list of dependency maps into one dictionary.\n\n Dependency maps have the following structure:\n\n ```python\n DEPENDENCIES_MAP = {\n # The first key in the map is a Bazel package\n # name of the workspace this file is defined in.\n \"workspace_member_package\": {\n\n # Not all dependencies are supported for all platforms.\n # the condition key is the condition required to be true\n # on the host platform.\n \"condition\": {\n\n # An alias to a crate target. # The label of the crate target the\n # Aliases are only crate names. # package name refers to.\n \"package_name\": \"@full//:label\",\n }\n }\n }\n ```\n\n Args:\n all_dependency_maps (list): A list of dicts as described above\n\n Returns:\n dict: A dictionary as described above\n \"\"\"\n dependencies = {}\n\n for workspace_deps_map in all_dependency_maps:\n for pkg_name, conditional_deps_map in workspace_deps_map.items():\n if pkg_name not in dependencies:\n non_frozen_map = dict()\n for key, values in conditional_deps_map.items():\n non_frozen_map.update({key: dict(values.items())})\n dependencies.setdefault(pkg_name, non_frozen_map)\n continue\n\n for condition, deps_map in conditional_deps_map.items():\n # If the condition has not been recorded, do so and continue\n if condition not in dependencies[pkg_name]:\n dependencies[pkg_name].setdefault(condition, dict(deps_map.items()))\n continue\n\n # Alert on any miss-matched dependencies\n inconsistent_entries = []\n for crate_name, crate_label in deps_map.items():\n existing = dependencies[pkg_name][condition].get(crate_name)\n if existing and existing != crate_label:\n inconsistent_entries.append((crate_name, existing, crate_label))\n dependencies[pkg_name][condition].update({crate_name: crate_label})\n\n return dependencies\n\ndef crate_deps(deps, package_name = None):\n \"\"\"Finds the fully qualified label of the requested crates for the package where this macro is called.\n\n Args:\n deps (list): The desired list of crate targets.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()`.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if not deps:\n return []\n\n if package_name == None:\n package_name = native.package_name()\n\n # Join both sets of dependencies\n dependencies = _flatten_dependency_maps([\n _NORMAL_DEPENDENCIES,\n _NORMAL_DEV_DEPENDENCIES,\n _PROC_MACRO_DEPENDENCIES,\n _PROC_MACRO_DEV_DEPENDENCIES,\n _BUILD_DEPENDENCIES,\n _BUILD_PROC_MACRO_DEPENDENCIES,\n ]).pop(package_name, {})\n\n # Combine all conditional packages so we can easily index over a flat list\n # TODO: Perhaps this should actually return select statements and maintain\n # the conditionals of the dependencies\n flat_deps = {}\n for deps_set in dependencies.values():\n for crate_name, crate_label in deps_set.items():\n flat_deps.update({crate_name: crate_label})\n\n missing_crates = []\n crate_targets = []\n for crate_target in deps:\n if crate_target not in flat_deps:\n missing_crates.append(crate_target)\n else:\n crate_targets.append(flat_deps[crate_target])\n\n if missing_crates:\n fail(\"Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`\".format(\n missing_crates,\n package_name,\n dependencies,\n ))\n\n return crate_targets\n\ndef all_crate_deps(\n normal = False, \n normal_dev = False, \n proc_macro = False, \n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Finds the fully qualified label of all requested direct crate dependencies \\\n for the package where this macro is called.\n\n If no parameters are set, all normal dependencies are returned. Setting any one flag will\n otherwise impact the contents of the returned list.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list.\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_dependency_maps = []\n if normal:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n if normal_dev:\n all_dependency_maps.append(_NORMAL_DEV_DEPENDENCIES)\n if proc_macro:\n all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES)\n if proc_macro_dev:\n all_dependency_maps.append(_PROC_MACRO_DEV_DEPENDENCIES)\n if build:\n all_dependency_maps.append(_BUILD_DEPENDENCIES)\n if build_proc_macro:\n all_dependency_maps.append(_BUILD_PROC_MACRO_DEPENDENCIES)\n\n # Default to always using normal dependencies\n if not all_dependency_maps:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n\n dependencies = _flatten_dependency_maps(all_dependency_maps).pop(package_name, None)\n\n if not dependencies:\n if dependencies == None:\n fail(\"Tried to get all_crate_deps for package \" + package_name + \" but that package had no Cargo.toml file\")\n else:\n return []\n\n crate_deps = list(dependencies.pop(_COMMON_CONDITION, {}).values())\n for condition, deps in dependencies.items():\n crate_deps += selects.with_or({\n tuple(_CONDITIONS[condition]): deps.values(),\n \"//conditions:default\": [],\n })\n\n return crate_deps\n\ndef aliases(\n normal = False,\n normal_dev = False,\n proc_macro = False,\n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Produces a map of Crate alias names to their original label\n\n If no dependency kinds are specified, `normal` and `proc_macro` are used by default.\n Setting any one flag will otherwise determine the contents of the returned dict.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list..\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n dict: The aliases of all associated packages\n \"\"\"\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_aliases_maps = []\n if normal:\n all_aliases_maps.append(_NORMAL_ALIASES)\n if normal_dev:\n all_aliases_maps.append(_NORMAL_DEV_ALIASES)\n if proc_macro:\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n if proc_macro_dev:\n all_aliases_maps.append(_PROC_MACRO_DEV_ALIASES)\n if build:\n all_aliases_maps.append(_BUILD_ALIASES)\n if build_proc_macro:\n all_aliases_maps.append(_BUILD_PROC_MACRO_ALIASES)\n\n # Default to always using normal aliases\n if not all_aliases_maps:\n all_aliases_maps.append(_NORMAL_ALIASES)\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n\n aliases = _flatten_dependency_maps(all_aliases_maps).pop(package_name, None)\n\n if not aliases:\n return dict()\n\n common_items = aliases.pop(_COMMON_CONDITION, {}).items()\n\n # If there are only common items in the dictionary, immediately return them\n if not len(aliases.keys()) == 1:\n return dict(common_items)\n\n # Build a single select statement where each conditional has accounted for the\n # common set of aliases.\n crate_aliases = {\"//conditions:default\": dict(common_items)}\n for condition, deps in aliases.items():\n condition_triples = _CONDITIONS[condition]\n for triple in condition_triples:\n if triple in crate_aliases:\n crate_aliases[triple].update(deps)\n else:\n crate_aliases.update({triple: dict(deps.items() + common_items)})\n\n return select(crate_aliases)\n\n###############################################################################\n# WORKSPACE MEMBER DEPS AND ALIASES\n###############################################################################\n\n_NORMAL_DEPENDENCIES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n \"argon2\": Label(\"@crates//:argon2-0.5.3\"),\n \"dirs\": Label(\"@crates//:dirs-5.0.1\"),\n \"libc\": Label(\"@crates//:libc-0.2.186\"),\n \"once_cell\": Label(\"@crates//:once_cell-1.21.4\"),\n \"openssl\": Label(\"@crates//:openssl-0.10.80\"),\n \"parking_lot\": Label(\"@crates//:parking_lot-0.12.5\"),\n \"parsec-client\": Label(\"@crates//:parsec-client-0.16.0\"),\n \"serde\": Label(\"@crates//:serde-1.0.228\"),\n \"serde_json\": Label(\"@crates//:serde_json-1.0.150\"),\n \"tempfile\": Label(\"@crates//:tempfile-3.27.0\"),\n \"toml\": Label(\"@crates//:toml-0.8.19\"),\n \"zeroize\": Label(\"@crates//:zeroize-1.8.2\"),\n },\n },\n}\n\n\n_NORMAL_ALIASES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_NORMAL_DEV_DEPENDENCIES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n \"serial_test\": Label(\"@crates//:serial_test-3.5.0\"),\n },\n },\n}\n\n\n_NORMAL_DEV_ALIASES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_PROC_MACRO_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_PROC_MACRO_ALIASES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_PROC_MACRO_DEV_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_PROC_MACRO_DEV_ALIASES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_BUILD_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_BUILD_ALIASES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_ALIASES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_CONDITIONS = {\n \"aarch64-linux-android\": [],\n \"aarch64-pc-windows-gnullvm\": [],\n \"aarch64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\"],\n \"aarch64-unknown-nto-qnx800\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\"],\n \"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [],\n \"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), not(any(all(target_os = \\\"linux\\\", target_env = \\\"\\\"), getrandom_backend = \\\"custom\\\", getrandom_backend = \\\"linux_raw\\\", getrandom_backend = \\\"rdrand\\\", getrandom_backend = \\\"rndr\\\"))))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\"],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_os = \\\"linux\\\"))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\"],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_vendor = \\\"apple\\\"))\": [],\n \"cfg(all(target_arch = \\\"loongarch64\\\", target_os = \\\"linux\\\"))\": [],\n \"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"wasi\\\", target_env = \\\"p2\\\"))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"gnu\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86_64\\\", target_env = \\\"gnu\\\", not(target_abi = \\\"llvm\\\"), not(windows_raw_dylib)))\": [\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(all(target_arch = \\\"x86_64\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_os = \\\"uefi\\\", getrandom_backend = \\\"efi_rng\\\"))\": [],\n \"cfg(any())\": [],\n \"cfg(any(target_arch = \\\"x86\\\", target_arch = \\\"x86_64\\\"))\": [\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(any(target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"hurd\\\", target_os = \\\"illumos\\\", target_os = \\\"cygwin\\\", all(target_os = \\\"horizon\\\", target_arch = \\\"arm\\\")))\": [],\n \"cfg(any(target_os = \\\"haiku\\\", target_os = \\\"redox\\\", target_os = \\\"nto\\\", target_os = \\\"aix\\\"))\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\"],\n \"cfg(any(target_os = \\\"ios\\\", target_os = \\\"visionos\\\", target_os = \\\"watchos\\\", target_os = \\\"tvos\\\"))\": [],\n \"cfg(any(target_os = \\\"macos\\\", target_os = \\\"openbsd\\\", target_os = \\\"vita\\\", target_os = \\\"emscripten\\\"))\": [],\n \"cfg(any(unix, target_os = \\\"wasi\\\"))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(target_os = \\\"hermit\\\")\": [],\n \"cfg(target_os = \\\"netbsd\\\")\": [],\n \"cfg(target_os = \\\"redox\\\")\": [],\n \"cfg(target_os = \\\"solaris\\\")\": [],\n \"cfg(target_os = \\\"vxworks\\\")\": [],\n \"cfg(target_os = \\\"wasi\\\")\": [],\n \"cfg(unix)\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(windows)\": [],\n \"x86_64-pc-nto-qnx800\": [\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\"],\n \"x86_64-pc-windows-gnullvm\": [],\n \"x86_64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n}\n\n###############################################################################\n\ndef crate_repositories():\n \"\"\"A macro for defining repositories for all generated crates.\n\n Returns:\n A list of repos visible to the module through the module extension.\n \"\"\"\n maybe(\n http_archive,\n name = \"crates__aho-corasick-1.1.4\",\n sha256 = \"ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aho-corasick/1.1.4/download\"],\n strip_prefix = \"aho-corasick-1.1.4\",\n build_file = Label(\"@crates//crates:BUILD.aho-corasick-1.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anyhow-1.0.102\",\n sha256 = \"7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anyhow/1.0.102/download\"],\n strip_prefix = \"anyhow-1.0.102\",\n build_file = Label(\"@crates//crates:BUILD.anyhow-1.0.102.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__argon2-0.5.3\",\n sha256 = \"3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/argon2/0.5.3/download\"],\n strip_prefix = \"argon2-0.5.3\",\n build_file = Label(\"@crates//crates:BUILD.argon2-0.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__autocfg-1.5.1\",\n sha256 = \"f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/autocfg/1.5.1/download\"],\n strip_prefix = \"autocfg-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.autocfg-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__base64ct-1.6.0\",\n sha256 = \"8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/base64ct/1.6.0/download\"],\n strip_prefix = \"base64ct-1.6.0\",\n build_file = Label(\"@crates//crates:BUILD.base64ct-1.6.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bincode-1.3.3\",\n sha256 = \"b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bincode/1.3.3/download\"],\n strip_prefix = \"bincode-1.3.3\",\n build_file = Label(\"@crates//crates:BUILD.bincode-1.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bitflags-2.11.1\",\n sha256 = \"c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bitflags/2.11.1/download\"],\n strip_prefix = \"bitflags-2.11.1\",\n build_file = Label(\"@crates//crates:BUILD.bitflags-2.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__blake2-0.10.6\",\n sha256 = \"46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/blake2/0.10.6/download\"],\n strip_prefix = \"blake2-0.10.6\",\n build_file = Label(\"@crates//crates:BUILD.blake2-0.10.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__block-buffer-0.10.4\",\n sha256 = \"3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/block-buffer/0.10.4/download\"],\n strip_prefix = \"block-buffer-0.10.4\",\n build_file = Label(\"@crates//crates:BUILD.block-buffer-0.10.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytes-1.11.1\",\n sha256 = \"1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytes/1.11.1/download\"],\n strip_prefix = \"bytes-1.11.1\",\n build_file = Label(\"@crates//crates:BUILD.bytes-1.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cc-1.2.63\",\n sha256 = \"556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cc/1.2.63/download\"],\n strip_prefix = \"cc-1.2.63\",\n build_file = Label(\"@crates//crates:BUILD.cc-1.2.63.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg-if-1.0.4\",\n sha256 = \"9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg-if/1.0.4/download\"],\n strip_prefix = \"cfg-if-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.cfg-if-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cmake-0.1.58\",\n sha256 = \"c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cmake/0.1.58/download\"],\n strip_prefix = \"cmake-0.1.58\",\n build_file = Label(\"@crates//crates:BUILD.cmake-0.1.58.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cpufeatures-0.2.17\",\n sha256 = \"59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cpufeatures/0.2.17/download\"],\n strip_prefix = \"cpufeatures-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.cpufeatures-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crypto-common-0.1.7\",\n sha256 = \"78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crypto-common/0.1.7/download\"],\n strip_prefix = \"crypto-common-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.crypto-common-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__derivative-2.2.0\",\n sha256 = \"fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/derivative/2.2.0/download\"],\n strip_prefix = \"derivative-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.derivative-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__digest-0.10.7\",\n sha256 = \"9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/digest/0.10.7/download\"],\n strip_prefix = \"digest-0.10.7\",\n build_file = Label(\"@crates//crates:BUILD.digest-0.10.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dirs-5.0.1\",\n sha256 = \"44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dirs/5.0.1/download\"],\n strip_prefix = \"dirs-5.0.1\",\n build_file = Label(\"@crates//crates:BUILD.dirs-5.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dirs-sys-0.4.1\",\n sha256 = \"520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dirs-sys/0.4.1/download\"],\n strip_prefix = \"dirs-sys-0.4.1\",\n build_file = Label(\"@crates//crates:BUILD.dirs-sys-0.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__displaydoc-0.2.6\",\n sha256 = \"1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/displaydoc/0.2.6/download\"],\n strip_prefix = \"displaydoc-0.2.6\",\n build_file = Label(\"@crates//crates:BUILD.displaydoc-0.2.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__either-1.16.0\",\n sha256 = \"91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/either/1.16.0/download\"],\n strip_prefix = \"either-1.16.0\",\n build_file = Label(\"@crates//crates:BUILD.either-1.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__equivalent-1.0.2\",\n sha256 = \"877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/equivalent/1.0.2/download\"],\n strip_prefix = \"equivalent-1.0.2\",\n build_file = Label(\"@crates//crates:BUILD.equivalent-1.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__errno-0.3.14\",\n sha256 = \"39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/errno/0.3.14/download\"],\n strip_prefix = \"errno-0.3.14\",\n build_file = Label(\"@crates//crates:BUILD.errno-0.3.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fastrand-2.4.1\",\n sha256 = \"9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fastrand/2.4.1/download\"],\n strip_prefix = \"fastrand-2.4.1\",\n build_file = Label(\"@crates//crates:BUILD.fastrand-2.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__find-msvc-tools-0.1.9\",\n sha256 = \"5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/find-msvc-tools/0.1.9/download\"],\n strip_prefix = \"find-msvc-tools-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.find-msvc-tools-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-0.3.2\",\n sha256 = \"f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types/0.3.2/download\"],\n strip_prefix = \"foreign-types-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-shared-0.1.1\",\n sha256 = \"00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types-shared/0.1.1/download\"],\n strip_prefix = \"foreign-types-shared-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-shared-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__form_urlencoded-1.2.2\",\n sha256 = \"cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/form_urlencoded/1.2.2/download\"],\n strip_prefix = \"form_urlencoded-1.2.2\",\n build_file = Label(\"@crates//crates:BUILD.form_urlencoded-1.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-core-0.3.32\",\n sha256 = \"7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-core/0.3.32/download\"],\n strip_prefix = \"futures-core-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-core-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-executor-0.3.32\",\n sha256 = \"baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-executor/0.3.32/download\"],\n strip_prefix = \"futures-executor-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-executor-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-task-0.3.32\",\n sha256 = \"037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-task/0.3.32/download\"],\n strip_prefix = \"futures-task-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-task-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-util-0.3.32\",\n sha256 = \"389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-util/0.3.32/download\"],\n strip_prefix = \"futures-util-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-util-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__generic-array-0.14.7\",\n sha256 = \"85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/generic-array/0.14.7/download\"],\n strip_prefix = \"generic-array-0.14.7\",\n build_file = Label(\"@crates//crates:BUILD.generic-array-0.14.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.2.17\",\n sha256 = \"ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.2.17/download\"],\n strip_prefix = \"getrandom-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.3.4\",\n sha256 = \"899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.3.4/download\"],\n strip_prefix = \"getrandom-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.14.5\",\n sha256 = \"e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.14.5/download\"],\n strip_prefix = \"hashbrown-0.14.5\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.14.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_collections-1.5.0\",\n sha256 = \"db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_collections/1.5.0/download\"],\n strip_prefix = \"icu_collections-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_collections-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locid-1.5.0\",\n sha256 = \"13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locid/1.5.0/download\"],\n strip_prefix = \"icu_locid-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locid-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locid_transform-1.5.0\",\n sha256 = \"01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locid_transform/1.5.0/download\"],\n strip_prefix = \"icu_locid_transform-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locid_transform-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locid_transform_data-1.5.1\",\n sha256 = \"7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locid_transform_data/1.5.1/download\"],\n strip_prefix = \"icu_locid_transform_data-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_locid_transform_data-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_normalizer-1.5.0\",\n sha256 = \"19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_normalizer/1.5.0/download\"],\n strip_prefix = \"icu_normalizer-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_normalizer-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_normalizer_data-1.5.1\",\n sha256 = \"c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_normalizer_data/1.5.1/download\"],\n strip_prefix = \"icu_normalizer_data-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_normalizer_data-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_properties-1.5.1\",\n sha256 = \"93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_properties/1.5.1/download\"],\n strip_prefix = \"icu_properties-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_properties-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_properties_data-1.5.1\",\n sha256 = \"85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_properties_data/1.5.1/download\"],\n strip_prefix = \"icu_properties_data-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_properties_data-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_provider-1.5.0\",\n sha256 = \"6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_provider/1.5.0/download\"],\n strip_prefix = \"icu_provider-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_provider-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_provider_macros-1.5.0\",\n sha256 = \"1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_provider_macros/1.5.0/download\"],\n strip_prefix = \"icu_provider_macros-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_provider_macros-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__idna-1.0.3\",\n sha256 = \"686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/idna/1.0.3/download\"],\n strip_prefix = \"idna-1.0.3\",\n build_file = Label(\"@crates//crates:BUILD.idna-1.0.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__idna_adapter-1.2.0\",\n sha256 = \"daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/idna_adapter/1.2.0/download\"],\n strip_prefix = \"idna_adapter-1.2.0\",\n build_file = Label(\"@crates//crates:BUILD.idna_adapter-1.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__indexmap-2.0.0\",\n sha256 = \"d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/indexmap/2.0.0/download\"],\n strip_prefix = \"indexmap-2.0.0\",\n build_file = Label(\"@crates//crates:BUILD.indexmap-2.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itertools-0.10.5\",\n sha256 = \"b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itertools/0.10.5/download\"],\n strip_prefix = \"itertools-0.10.5\",\n build_file = Label(\"@crates//crates:BUILD.itertools-0.10.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itoa-1.0.18\",\n sha256 = \"8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itoa/1.0.18/download\"],\n strip_prefix = \"itoa-1.0.18\",\n build_file = Label(\"@crates//crates:BUILD.itoa-1.0.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libc-0.2.186\",\n sha256 = \"68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libc/0.2.186/download\"],\n strip_prefix = \"libc-0.2.186\",\n build_file = Label(\"@crates//crates:BUILD.libc-0.2.186.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libredox-0.1.17\",\n sha256 = \"f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libredox/0.1.17/download\"],\n strip_prefix = \"libredox-0.1.17\",\n build_file = Label(\"@crates//crates:BUILD.libredox-0.1.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__linux-raw-sys-0.12.1\",\n sha256 = \"32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/linux-raw-sys/0.12.1/download\"],\n strip_prefix = \"linux-raw-sys-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.linux-raw-sys-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__litemap-0.7.5\",\n sha256 = \"23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/litemap/0.7.5/download\"],\n strip_prefix = \"litemap-0.7.5\",\n build_file = Label(\"@crates//crates:BUILD.litemap-0.7.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__lock_api-0.4.14\",\n sha256 = \"224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/lock_api/0.4.14/download\"],\n strip_prefix = \"lock_api-0.4.14\",\n build_file = Label(\"@crates//crates:BUILD.lock_api-0.4.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__log-0.4.30\",\n sha256 = \"616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/log/0.4.30/download\"],\n strip_prefix = \"log-0.4.30\",\n build_file = Label(\"@crates//crates:BUILD.log-0.4.30.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memchr-2.8.1\",\n sha256 = \"6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memchr/2.8.1/download\"],\n strip_prefix = \"memchr-2.8.1\",\n build_file = Label(\"@crates//crates:BUILD.memchr-2.8.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-0.4.3\",\n sha256 = \"35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num/0.4.3/download\"],\n strip_prefix = \"num-0.4.3\",\n build_file = Label(\"@crates//crates:BUILD.num-0.4.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-bigint-0.4.6\",\n sha256 = \"a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-bigint/0.4.6/download\"],\n strip_prefix = \"num-bigint-0.4.6\",\n build_file = Label(\"@crates//crates:BUILD.num-bigint-0.4.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-complex-0.4.6\",\n sha256 = \"73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-complex/0.4.6/download\"],\n strip_prefix = \"num-complex-0.4.6\",\n build_file = Label(\"@crates//crates:BUILD.num-complex-0.4.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-derive-0.4.2\",\n sha256 = \"ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-derive/0.4.2/download\"],\n strip_prefix = \"num-derive-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.num-derive-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-integer-0.1.46\",\n sha256 = \"7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-integer/0.1.46/download\"],\n strip_prefix = \"num-integer-0.1.46\",\n build_file = Label(\"@crates//crates:BUILD.num-integer-0.1.46.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-iter-0.1.45\",\n sha256 = \"1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-iter/0.1.45/download\"],\n strip_prefix = \"num-iter-0.1.45\",\n build_file = Label(\"@crates//crates:BUILD.num-iter-0.1.45.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-rational-0.4.2\",\n sha256 = \"f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-rational/0.4.2/download\"],\n strip_prefix = \"num-rational-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.num-rational-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-traits-0.2.19\",\n sha256 = \"071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-traits/0.2.19/download\"],\n strip_prefix = \"num-traits-0.2.19\",\n build_file = Label(\"@crates//crates:BUILD.num-traits-0.2.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__once_cell-1.21.4\",\n sha256 = \"9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/once_cell/1.21.4/download\"],\n strip_prefix = \"once_cell-1.21.4\",\n build_file = Label(\"@crates//crates:BUILD.once_cell-1.21.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__openssl-0.10.80\",\n sha256 = \"a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/openssl/0.10.80/download\"],\n strip_prefix = \"openssl-0.10.80\",\n build_file = Label(\"@crates//crates:BUILD.openssl-0.10.80.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__openssl-macros-0.1.1\",\n sha256 = \"a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/openssl-macros/0.1.1/download\"],\n strip_prefix = \"openssl-macros-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.openssl-macros-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__openssl-sys-0.9.116\",\n patch_args = [\n \"-p1\",\n ],\n patches = [\n \"@@//third_party/patches:openssl_sys_build_rs.patch\",\n ],\n sha256 = \"f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/openssl-sys/0.9.116/download\"],\n strip_prefix = \"openssl-sys-0.9.116\",\n build_file = Label(\"@crates//crates:BUILD.openssl-sys-0.9.116.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__option-ext-0.2.0\",\n sha256 = \"04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/option-ext/0.2.0/download\"],\n strip_prefix = \"option-ext-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.option-ext-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking_lot-0.12.5\",\n sha256 = \"93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking_lot/0.12.5/download\"],\n strip_prefix = \"parking_lot-0.12.5\",\n build_file = Label(\"@crates//crates:BUILD.parking_lot-0.12.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking_lot_core-0.9.12\",\n sha256 = \"2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking_lot_core/0.9.12/download\"],\n strip_prefix = \"parking_lot_core-0.9.12\",\n build_file = Label(\"@crates//crates:BUILD.parking_lot_core-0.9.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parsec-client-0.16.0\",\n sha256 = \"a36f9d8e27166cf0586913812454174286e094d594cc8b28d8a8d02d64406bbc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parsec-client/0.16.0/download\"],\n strip_prefix = \"parsec-client-0.16.0\",\n build_file = Label(\"@crates//crates:BUILD.parsec-client-0.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parsec-interface-0.29.1\",\n sha256 = \"cc706e09209b30f10baa35709d41b9cc01d4931b21c00679f59db96cd1650add\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parsec-interface/0.29.1/download\"],\n strip_prefix = \"parsec-interface-0.29.1\",\n build_file = Label(\"@crates//crates:BUILD.parsec-interface-0.29.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__password-hash-0.5.0\",\n sha256 = \"346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/password-hash/0.5.0/download\"],\n strip_prefix = \"password-hash-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.password-hash-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__percent-encoding-2.3.2\",\n sha256 = \"9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/percent-encoding/2.3.2/download\"],\n strip_prefix = \"percent-encoding-2.3.2\",\n build_file = Label(\"@crates//crates:BUILD.percent-encoding-2.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pin-project-lite-0.2.17\",\n sha256 = \"a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pin-project-lite/0.2.17/download\"],\n strip_prefix = \"pin-project-lite-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.pin-project-lite-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pkg-config-0.3.33\",\n sha256 = \"19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pkg-config/0.3.33/download\"],\n strip_prefix = \"pkg-config-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.pkg-config-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__proc-macro2-1.0.106\",\n sha256 = \"8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/proc-macro2/1.0.106/download\"],\n strip_prefix = \"proc-macro2-1.0.106\",\n build_file = Label(\"@crates//crates:BUILD.proc-macro2-1.0.106.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__prost-0.9.0\",\n sha256 = \"444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/prost/0.9.0/download\"],\n strip_prefix = \"prost-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.prost-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__prost-derive-0.9.0\",\n sha256 = \"f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/prost-derive/0.9.0/download\"],\n strip_prefix = \"prost-derive-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.prost-derive-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__psa-crypto-0.12.0\",\n sha256 = \"89c2256e525b9a45ec3bbb3382a43dd8809240279e0aab8ea7ee220e9295445b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/psa-crypto/0.12.0/download\"],\n strip_prefix = \"psa-crypto-0.12.0\",\n build_file = Label(\"@crates//crates:BUILD.psa-crypto-0.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__psa-crypto-sys-0.12.0\",\n sha256 = \"f170cac3a328e1678916b276067ec170a5a51db1b9b8b4c00b44c2839819a963\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/psa-crypto-sys/0.12.0/download\"],\n strip_prefix = \"psa-crypto-sys-0.12.0\",\n build_file = Label(\"@crates//crates:BUILD.psa-crypto-sys-0.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quote-1.0.45\",\n sha256 = \"41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quote/1.0.45/download\"],\n strip_prefix = \"quote-1.0.45\",\n build_file = Label(\"@crates//crates:BUILD.quote-1.0.45.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__r-efi-5.3.0\",\n sha256 = \"69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/r-efi/5.3.0/download\"],\n strip_prefix = \"r-efi-5.3.0\",\n build_file = Label(\"@crates//crates:BUILD.r-efi-5.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_core-0.6.4\",\n sha256 = \"ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_core/0.6.4/download\"],\n strip_prefix = \"rand_core-0.6.4\",\n build_file = Label(\"@crates//crates:BUILD.rand_core-0.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__redox_syscall-0.5.18\",\n sha256 = \"ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/redox_syscall/0.5.18/download\"],\n strip_prefix = \"redox_syscall-0.5.18\",\n build_file = Label(\"@crates//crates:BUILD.redox_syscall-0.5.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__redox_users-0.4.6\",\n sha256 = \"ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/redox_users/0.4.6/download\"],\n strip_prefix = \"redox_users-0.4.6\",\n build_file = Label(\"@crates//crates:BUILD.redox_users-0.4.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-1.12.3\",\n sha256 = \"e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex/1.12.3/download\"],\n strip_prefix = \"regex-1.12.3\",\n build_file = Label(\"@crates//crates:BUILD.regex-1.12.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-automata-0.4.14\",\n sha256 = \"6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-automata/0.4.14/download\"],\n strip_prefix = \"regex-automata-0.4.14\",\n build_file = Label(\"@crates//crates:BUILD.regex-automata-0.4.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-syntax-0.8.10\",\n sha256 = \"dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-syntax/0.8.10/download\"],\n strip_prefix = \"regex-syntax-0.8.10\",\n build_file = Label(\"@crates//crates:BUILD.regex-syntax-0.8.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustix-1.1.4\",\n sha256 = \"b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustix/1.1.4/download\"],\n strip_prefix = \"rustix-1.1.4\",\n build_file = Label(\"@crates//crates:BUILD.rustix-1.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__same-file-1.0.6\",\n sha256 = \"93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/same-file/1.0.6/download\"],\n strip_prefix = \"same-file-1.0.6\",\n build_file = Label(\"@crates//crates:BUILD.same-file-1.0.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__scopeguard-1.2.0\",\n sha256 = \"94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/scopeguard/1.2.0/download\"],\n strip_prefix = \"scopeguard-1.2.0\",\n build_file = Label(\"@crates//crates:BUILD.scopeguard-1.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__secrecy-0.8.0\",\n sha256 = \"9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/secrecy/0.8.0/download\"],\n strip_prefix = \"secrecy-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.secrecy-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde-1.0.228\",\n sha256 = \"9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde/1.0.228/download\"],\n strip_prefix = \"serde-1.0.228\",\n build_file = Label(\"@crates//crates:BUILD.serde-1.0.228.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_core-1.0.228\",\n sha256 = \"41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_core/1.0.228/download\"],\n strip_prefix = \"serde_core-1.0.228\",\n build_file = Label(\"@crates//crates:BUILD.serde_core-1.0.228.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_derive-1.0.228\",\n sha256 = \"d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_derive/1.0.228/download\"],\n strip_prefix = \"serde_derive-1.0.228\",\n build_file = Label(\"@crates//crates:BUILD.serde_derive-1.0.228.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_json-1.0.150\",\n sha256 = \"e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_json/1.0.150/download\"],\n strip_prefix = \"serde_json-1.0.150\",\n build_file = Label(\"@crates//crates:BUILD.serde_json-1.0.150.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_spanned-0.6.9\",\n sha256 = \"bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_spanned/0.6.9/download\"],\n strip_prefix = \"serde_spanned-0.6.9\",\n build_file = Label(\"@crates//crates:BUILD.serde_spanned-0.6.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serial_test-3.5.0\",\n sha256 = \"699f4197115b8a7e7ff19c9a315a4bd6fffec26cc4626ef45ecaea389e081c6d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serial_test/3.5.0/download\"],\n strip_prefix = \"serial_test-3.5.0\",\n build_file = Label(\"@crates//crates:BUILD.serial_test-3.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serial_test_derive-3.5.0\",\n sha256 = \"94e153fc76e1c6a068703d6d29c508a0b15c061c4b7e43da59cc097bc342673c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serial_test_derive/3.5.0/download\"],\n strip_prefix = \"serial_test_derive-3.5.0\",\n build_file = Label(\"@crates//crates:BUILD.serial_test_derive-3.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__shlex-2.0.1\",\n sha256 = \"f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/shlex/2.0.1/download\"],\n strip_prefix = \"shlex-2.0.1\",\n build_file = Label(\"@crates//crates:BUILD.shlex-2.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__slab-0.4.12\",\n sha256 = \"0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/slab/0.4.12/download\"],\n strip_prefix = \"slab-0.4.12\",\n build_file = Label(\"@crates//crates:BUILD.slab-0.4.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__smallvec-1.15.1\",\n sha256 = \"67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/smallvec/1.15.1/download\"],\n strip_prefix = \"smallvec-1.15.1\",\n build_file = Label(\"@crates//crates:BUILD.smallvec-1.15.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__stable_deref_trait-1.2.1\",\n sha256 = \"6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/stable_deref_trait/1.2.1/download\"],\n strip_prefix = \"stable_deref_trait-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.stable_deref_trait-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__subtle-2.6.1\",\n sha256 = \"13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/subtle/2.6.1/download\"],\n strip_prefix = \"subtle-2.6.1\",\n build_file = Label(\"@crates//crates:BUILD.subtle-2.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-1.0.109\",\n sha256 = \"72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/1.0.109/download\"],\n strip_prefix = \"syn-1.0.109\",\n build_file = Label(\"@crates//crates:BUILD.syn-1.0.109.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-2.0.117\",\n sha256 = \"e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/2.0.117/download\"],\n strip_prefix = \"syn-2.0.117\",\n build_file = Label(\"@crates//crates:BUILD.syn-2.0.117.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__synstructure-0.13.2\",\n sha256 = \"728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/synstructure/0.13.2/download\"],\n strip_prefix = \"synstructure-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.synstructure-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tempfile-3.27.0\",\n sha256 = \"32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tempfile/3.27.0/download\"],\n strip_prefix = \"tempfile-3.27.0\",\n build_file = Label(\"@crates//crates:BUILD.tempfile-3.27.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-1.0.69\",\n sha256 = \"b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror/1.0.69/download\"],\n strip_prefix = \"thiserror-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-impl-1.0.69\",\n sha256 = \"4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror-impl/1.0.69/download\"],\n strip_prefix = \"thiserror-impl-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-impl-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tinystr-0.7.6\",\n sha256 = \"9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tinystr/0.7.6/download\"],\n strip_prefix = \"tinystr-0.7.6\",\n build_file = Label(\"@crates//crates:BUILD.tinystr-0.7.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml-0.8.19\",\n sha256 = \"a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml/0.8.19/download\"],\n strip_prefix = \"toml-0.8.19\",\n build_file = Label(\"@crates//crates:BUILD.toml-0.8.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_datetime-0.6.11\",\n sha256 = \"22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_datetime/0.6.11/download\"],\n strip_prefix = \"toml_datetime-0.6.11\",\n build_file = Label(\"@crates//crates:BUILD.toml_datetime-0.6.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_edit-0.22.20\",\n sha256 = \"583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_edit/0.22.20/download\"],\n strip_prefix = \"toml_edit-0.22.20\",\n build_file = Label(\"@crates//crates:BUILD.toml_edit-0.22.20.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__typenum-1.20.1\",\n sha256 = \"b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/typenum/1.20.1/download\"],\n strip_prefix = \"typenum-1.20.1\",\n build_file = Label(\"@crates//crates:BUILD.typenum-1.20.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-ident-1.0.24\",\n sha256 = \"e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-ident/1.0.24/download\"],\n strip_prefix = \"unicode-ident-1.0.24\",\n build_file = Label(\"@crates//crates:BUILD.unicode-ident-1.0.24.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__url-2.5.4\",\n sha256 = \"32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/url/2.5.4/download\"],\n strip_prefix = \"url-2.5.4\",\n build_file = Label(\"@crates//crates:BUILD.url-2.5.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf16_iter-1.0.5\",\n sha256 = \"c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf16_iter/1.0.5/download\"],\n strip_prefix = \"utf16_iter-1.0.5\",\n build_file = Label(\"@crates//crates:BUILD.utf16_iter-1.0.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf8_iter-1.0.4\",\n sha256 = \"b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf8_iter/1.0.4/download\"],\n strip_prefix = \"utf8_iter-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.utf8_iter-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uuid-0.8.2\",\n sha256 = \"bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uuid/0.8.2/download\"],\n strip_prefix = \"uuid-0.8.2\",\n build_file = Label(\"@crates//crates:BUILD.uuid-0.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__vcpkg-0.2.15\",\n sha256 = \"accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/vcpkg/0.2.15/download\"],\n strip_prefix = \"vcpkg-0.2.15\",\n build_file = Label(\"@crates//crates:BUILD.vcpkg-0.2.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__version_check-0.9.5\",\n sha256 = \"0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/version_check/0.9.5/download\"],\n strip_prefix = \"version_check-0.9.5\",\n build_file = Label(\"@crates//crates:BUILD.version_check-0.9.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__walkdir-2.5.0\",\n sha256 = \"29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/walkdir/2.5.0/download\"],\n strip_prefix = \"walkdir-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.walkdir-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasi-0.11.1-wasi-snapshot-preview1\",\n sha256 = \"ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasi/0.11.1+wasi-snapshot-preview1/download\"],\n strip_prefix = \"wasi-0.11.1+wasi-snapshot-preview1\",\n build_file = Label(\"@crates//crates:BUILD.wasi-0.11.1+wasi-snapshot-preview1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasip2-1.0.3-wasi-0.2.9\",\n sha256 = \"20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasip2/1.0.3+wasi-0.2.9/download\"],\n strip_prefix = \"wasip2-1.0.3+wasi-0.2.9\",\n build_file = Label(\"@crates//crates:BUILD.wasip2-1.0.3+wasi-0.2.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-util-0.1.11\",\n sha256 = \"c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi-util/0.1.11/download\"],\n strip_prefix = \"winapi-util-0.1.11\",\n build_file = Label(\"@crates//crates:BUILD.winapi-util-0.1.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-link-0.2.1\",\n sha256 = \"f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-link/0.2.1/download\"],\n strip_prefix = \"windows-link-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-link-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.48.0\",\n sha256 = \"677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.48.0/download\"],\n strip_prefix = \"windows-sys-0.48.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.48.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.61.2\",\n sha256 = \"ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.61.2/download\"],\n strip_prefix = \"windows-sys-0.61.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.61.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-targets-0.48.5\",\n sha256 = \"9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-targets/0.48.5/download\"],\n strip_prefix = \"windows-targets-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows-targets-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_gnullvm-0.48.5\",\n sha256 = \"2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_gnullvm/0.48.5/download\"],\n strip_prefix = \"windows_aarch64_gnullvm-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_gnullvm-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_msvc-0.48.5\",\n sha256 = \"dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_msvc/0.48.5/download\"],\n strip_prefix = \"windows_aarch64_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnu-0.48.5\",\n sha256 = \"a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnu/0.48.5/download\"],\n strip_prefix = \"windows_i686_gnu-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnu-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_msvc-0.48.5\",\n sha256 = \"8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_msvc/0.48.5/download\"],\n strip_prefix = \"windows_i686_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnu-0.48.5\",\n sha256 = \"53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnu/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_gnu-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnu-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnullvm-0.48.5\",\n sha256 = \"0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnullvm/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_gnullvm-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnullvm-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_msvc-0.48.5\",\n sha256 = \"ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_msvc/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winnow-0.6.26\",\n sha256 = \"1e90edd2ac1aa278a5c4599b1d89cf03074b610800f866d4026dc199d7929a28\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winnow/0.6.26/download\"],\n strip_prefix = \"winnow-0.6.26\",\n build_file = Label(\"@crates//crates:BUILD.winnow-0.6.26.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wit-bindgen-0.57.1\",\n sha256 = \"1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wit-bindgen/0.57.1/download\"],\n strip_prefix = \"wit-bindgen-0.57.1\",\n build_file = Label(\"@crates//crates:BUILD.wit-bindgen-0.57.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__write16-1.0.0\",\n sha256 = \"d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/write16/1.0.0/download\"],\n strip_prefix = \"write16-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.write16-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__writeable-0.5.5\",\n sha256 = \"1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/writeable/0.5.5/download\"],\n strip_prefix = \"writeable-0.5.5\",\n build_file = Label(\"@crates//crates:BUILD.writeable-0.5.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yoke-0.7.5\",\n sha256 = \"120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yoke/0.7.5/download\"],\n strip_prefix = \"yoke-0.7.5\",\n build_file = Label(\"@crates//crates:BUILD.yoke-0.7.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yoke-derive-0.7.5\",\n sha256 = \"2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yoke-derive/0.7.5/download\"],\n strip_prefix = \"yoke-derive-0.7.5\",\n build_file = Label(\"@crates//crates:BUILD.yoke-derive-0.7.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerofrom-0.1.8\",\n sha256 = \"0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerofrom/0.1.8/download\"],\n strip_prefix = \"zerofrom-0.1.8\",\n build_file = Label(\"@crates//crates:BUILD.zerofrom-0.1.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerofrom-derive-0.1.7\",\n sha256 = \"11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerofrom-derive/0.1.7/download\"],\n strip_prefix = \"zerofrom-derive-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.zerofrom-derive-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zeroize-1.8.2\",\n sha256 = \"b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zeroize/1.8.2/download\"],\n strip_prefix = \"zeroize-1.8.2\",\n build_file = Label(\"@crates//crates:BUILD.zeroize-1.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zeroize_derive-1.4.3\",\n sha256 = \"85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zeroize_derive/1.4.3/download\"],\n strip_prefix = \"zeroize_derive-1.4.3\",\n build_file = Label(\"@crates//crates:BUILD.zeroize_derive-1.4.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerovec-0.10.4\",\n sha256 = \"aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerovec/0.10.4/download\"],\n strip_prefix = \"zerovec-0.10.4\",\n build_file = Label(\"@crates//crates:BUILD.zerovec-0.10.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerovec-derive-0.10.3\",\n sha256 = \"6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerovec-derive/0.10.3/download\"],\n strip_prefix = \"zerovec-derive-0.10.3\",\n build_file = Label(\"@crates//crates:BUILD.zerovec-derive-0.10.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zmij-1.0.21\",\n sha256 = \"b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zmij/1.0.21/download\"],\n strip_prefix = \"zmij-1.0.21\",\n build_file = Label(\"@crates//crates:BUILD.zmij-1.0.21.bazel\"),\n )\n\n return [\n struct(repo=\"crates__argon2-0.5.3\", is_dev_dep = False),\n struct(repo=\"crates__dirs-5.0.1\", is_dev_dep = False),\n struct(repo=\"crates__libc-0.2.186\", is_dev_dep = False),\n struct(repo=\"crates__once_cell-1.21.4\", is_dev_dep = False),\n struct(repo=\"crates__openssl-0.10.80\", is_dev_dep = False),\n struct(repo=\"crates__parking_lot-0.12.5\", is_dev_dep = False),\n struct(repo=\"crates__parsec-client-0.16.0\", is_dev_dep = False),\n struct(repo=\"crates__serde-1.0.228\", is_dev_dep = False),\n struct(repo=\"crates__serde_json-1.0.150\", is_dev_dep = False),\n struct(repo=\"crates__tempfile-3.27.0\", is_dev_dep = False),\n struct(repo=\"crates__toml-0.8.19\", is_dev_dep = False),\n struct(repo=\"crates__zeroize-1.8.2\", is_dev_dep = False),\n struct(repo = \"crates__serial_test-3.5.0\", is_dev_dep = True),\n ]\n" } } }, @@ -9597,20 +9597,20 @@ "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"once_cell\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"alloc\",\n \"default\",\n \"race\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=once_cell\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\": [],\n \"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.21.4\",\n)\n" } }, - "crates__openssl-0.10.68": { + "crates__openssl-0.10.80": { "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", "attributes": { "patch_args": [], "patch_tool": "", "patches": [], "remote_patch_strip": 1, - "sha256": "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5", + "sha256": "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967", "type": "tar.gz", "urls": [ - "https://static.crates.io/crates/openssl/0.10.68/download" + "https://static.crates.io/crates/openssl/0.10.80/download" ], - "strip_prefix": "openssl-0.10.68", - "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"openssl\",\n deps = [\n \"@crates__bitflags-2.11.1//:bitflags\",\n \"@crates__cfg-if-1.0.4//:cfg_if\",\n \"@crates__foreign-types-0.3.2//:foreign_types\",\n \"@crates__libc-0.2.186//:libc\",\n \"@crates__once_cell-1.21.4//:once_cell\",\n \"@crates__openssl-0.10.68//:build_script_build\",\n \"@crates__openssl-sys-0.9.116//:openssl_sys\",\n ],\n proc_macro_deps = [\n \"@crates__openssl-macros-0.1.1//:openssl_macros\",\n ],\n aliases = {\n \"@crates__openssl-sys-0.9.116//:openssl_sys\": \"ffi\",\n },\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=openssl\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\": [],\n \"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.10.68\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n link_deps = [\n \"@crates__openssl-sys-0.9.116//:openssl_sys\",\n ],\n edition = \"2021\",\n pkg_name = \"openssl\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=openssl\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"0.10.68\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + "strip_prefix": "openssl-0.10.80", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"openssl\",\n deps = [\n \"@crates__bitflags-2.11.1//:bitflags\",\n \"@crates__cfg-if-1.0.4//:cfg_if\",\n \"@crates__foreign-types-0.3.2//:foreign_types\",\n \"@crates__libc-0.2.186//:libc\",\n \"@crates__openssl-0.10.80//:build_script_build\",\n \"@crates__openssl-sys-0.9.116//:openssl_sys\",\n ],\n proc_macro_deps = [\n \"@crates__openssl-macros-0.1.1//:openssl_macros\",\n ],\n aliases = {\n \"@crates__openssl-sys-0.9.116//:openssl_sys\": \"ffi\",\n },\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=openssl\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\": [],\n \"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.10.80\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n link_deps = [\n \"@crates__openssl-sys-0.9.116//:openssl_sys\",\n ],\n edition = \"2021\",\n pkg_name = \"openssl\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=openssl\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"0.10.80\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" } }, "crates__openssl-macros-0.1.1": { From ac7da95086982dc08d0bfa101d5fb23c1033b49e Mon Sep 17 00:00:00 2001 From: HeHa112 <113408507+HeHa112@users.noreply.github.com> Date: Thu, 3 Sep 2026 13:42:36 +0200 Subject: [PATCH 11/12] iav_primula: add first integration dummy * git commit -m "iav_primula: add Rust FFI API stubs" * git commit -m "iav_primula: remove obsolete hello-world sources" * crypto-daemon: add PQC algorithm metadata * crypto-daemon: align PQC metadata with OS source layout Remove incorrectly introduced internal-repository paths and integrate the PQC algorithm metadata into the existing OS repository structure. * crypto-daemon: add PQC operation identifiers * score-provider: add generic signature operations * score-provider: add generic verification operations * score-provider: add generic kem operations * score-provider: extend handler factory for PQC * iav_primula: add provider and backend registration * feat: add iav_primula key management to score provider Add Primula key factory and key handler implementations and integrate them into the score provider library with the required FFI dependencies. * iav_primula: add signature handler * iav_primula: add verification handler Add the iav_primula verification handler and register its sources and headers in the score provider library. * iav_primula: add KEM handler * iav_primula: Add the iav_primula signature handler * iav_primula: add verification, KEM and integration tests * iav_primula: enable CI tests and fix backend integration * iav_primula: enable backend by default * iav_primula: set provider_type: to SPECIALIZED * iav_primula: update MODULE.bazel * iav_primula: MODULE.bazel roll back * iav_primula: clarify crypto-daemon documentation * iav_primula: document signature and verification handlers * iav_primula: document generic KEM handlers * iav_primula: comment generic sign and verify handlers * iav_primula: comment IAV-Primula test cases * Applied formatting to iav_* files * iav_primula: comment FFI interface and tests * iav_primula: refactor include guard names * iav_primula: add file documentation * Housekeeping tasks. * iav_primula: review findings fixed * fixed review findings. * fixed derp --------- Co-authored-by: Markus Mergner --- score/crypto/src/backend/BUILD | 2 +- score/crypto/src/backend/README.md | 2 +- score/crypto/src/backend/score_provider/BUILD | 14 +- .../score_provider/active_backends_list.hpp | 2 +- .../backend/score_provider/iav_primula/BUILD | 39 +++ .../iav_primula/primula_backend_adapter.cpp | 37 +++ .../iav_primula/primula_backend_adapter.hpp | 62 +++++ score/crypto/src/daemon/common/BUILD | 3 + score/crypto/src/daemon/common/actors.hpp | 3 + .../src/daemon/common/algorithm_info.hpp | 79 +++++- .../src/daemon/common/operation_names.hpp | 67 ++++- score/crypto/src/daemon/common/types.hpp | 3 + .../crypto/src/daemon/provider/handler/BUILD | 21 ++ .../operations/kem_handler_operations.hpp | 42 +++ .../operations/sign_handler_operations.hpp | 46 ++++ .../operations/verify_handler_operations.hpp | 44 ++++ .../src/daemon/provider/score_provider/BUILD | 42 +++ .../iav_primula/iav_primula_provider.cpp | 75 ++++++ .../iav_primula/iav_primula_provider.hpp | 65 +++++ .../iav_primula_key_factory.cpp | 122 +++++++++ .../iav_primula_key_factory.hpp | 57 ++++ .../iav_primula_key_handler.cpp | 77 ++++++ .../iav_primula_key_handler.hpp | 90 +++++++ .../factory/iav_primula_handler_factory.cpp | 87 ++++++ .../factory/iav_primula_handler_factory.hpp | 76 ++++++ .../kem/iav_primula_kem_handler.cpp | 151 +++++++++++ .../kem/iav_primula_kem_handler.hpp | 81 ++++++ .../sign/iav_primula_sign_handler.cpp | 191 ++++++++++++++ .../sign/iav_primula_sign_handler.hpp | 79 ++++++ .../verify/iav_primula_verify_handler.cpp | 115 ++++++++ .../verify/iav_primula_verify_handler.hpp | 76 ++++++ .../score_provider/iav_primula/tests/BUILD | 41 +++ .../tests/iav_primula_kem_test.cpp | 126 +++++++++ .../tests/iav_primula_key_management_test.cpp | 96 +++++++ .../tests/iav_primula_signature_test.cpp | 75 ++++++ .../tests/iav_primula_verification_test.cpp | 96 +++++++ .../iav_primula/tests/integration_tests/BUILD | 14 + ...v_primula_application_integration_test.cpp | 103 ++++++++ .../factory/score_handler_factory.hpp | 36 ++- .../factory/src/score_handler_factory.cpp | 42 ++- .../score_provider/operations/kem/BUILD | 12 + .../operations/kem/kem_executor.hpp | 53 ++++ .../operations/kem/score_kem_handler.hpp | 86 ++++++ .../operations/kem/src/kem_executor.cpp | 72 +++++ .../operations/kem/src/score_kem_handler.cpp | 66 +++++ .../score_provider/operations/sign/BUILD | 13 + .../operations/sign/score_sign_handler.hpp | 143 ++++++++++ .../operations/sign/sign_executor.hpp | 120 +++++++++ .../sign/src/score_sign_handler.cpp | 85 ++++++ .../operations/sign/src/sign_executor.cpp | 247 ++++++++++++++++++ .../score_provider/operations/verify/BUILD | 13 + .../verify/score_verify_handler.hpp | 144 ++++++++++ .../verify/src/score_verify_handler.cpp | 91 +++++++ .../operations/verify/src/verify_executor.cpp | 244 +++++++++++++++++ .../operations/verify/verify_executor.hpp | 111 ++++++++ .../score_provider/score_provider_config.hpp | 2 +- score/iav_primula/BUILD | 24 +- score/iav_primula/include/iav_primula_ffi.h | 188 +++++++++++++ score/iav_primula/src/ffi.rs | 206 +++++++++++++++ score/iav_primula/src/main.rs | 16 -- score/iav_primula/tests/BUILD | 4 +- score/iav_primula/tests/ffi_test.rs | 101 +++++++ score/iav_primula/tests/hello_test.rs | 19 -- tests/iav_primula/BUILD | 17 ++ 64 files changed, 4498 insertions(+), 58 deletions(-) create mode 100644 score/crypto/src/backend/score_provider/iav_primula/BUILD create mode 100644 score/crypto/src/backend/score_provider/iav_primula/primula_backend_adapter.cpp create mode 100644 score/crypto/src/backend/score_provider/iav_primula/primula_backend_adapter.hpp create mode 100644 score/crypto/src/daemon/provider/handler/operations/kem_handler_operations.hpp create mode 100644 score/crypto/src/daemon/provider/handler/operations/sign_handler_operations.hpp create mode 100644 score/crypto/src/daemon/provider/handler/operations/verify_handler_operations.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/iav_primula_provider.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/iav_primula_provider.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_factory.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_factory.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/operations/factory/iav_primula_handler_factory.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/operations/factory/iav_primula_handler_factory.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/operations/kem/iav_primula_kem_handler.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/operations/kem/iav_primula_kem_handler.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/operations/sign/iav_primula_sign_handler.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/operations/sign/iav_primula_sign_handler.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/operations/verify/iav_primula_verify_handler.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/operations/verify/iav_primula_verify_handler.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/tests/BUILD create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_kem_test.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_key_management_test.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_signature_test.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_verification_test.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/tests/integration_tests/BUILD create mode 100644 score/crypto/src/daemon/provider/score_provider/iav_primula/tests/integration_tests/iav_primula_application_integration_test.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/kem/BUILD create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/kem/kem_executor.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/kem/score_kem_handler.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/kem/src/kem_executor.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/kem/src/score_kem_handler.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/sign/BUILD create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/sign/score_sign_handler.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/sign/sign_executor.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/sign/src/score_sign_handler.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/sign/src/sign_executor.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/verify/BUILD create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/verify/score_verify_handler.hpp create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/verify/src/score_verify_handler.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/verify/src/verify_executor.cpp create mode 100644 score/crypto/src/daemon/provider/score_provider/operations/verify/verify_executor.hpp create mode 100644 score/iav_primula/include/iav_primula_ffi.h create mode 100644 score/iav_primula/src/ffi.rs delete mode 100644 score/iav_primula/src/main.rs create mode 100644 score/iav_primula/tests/ffi_test.rs delete mode 100644 score/iav_primula/tests/hello_test.rs create mode 100644 tests/iav_primula/BUILD diff --git a/score/crypto/src/backend/BUILD b/score/crypto/src/backend/BUILD index 2c893eb03..da92afd71 100644 --- a/score/crypto/src/backend/BUILD +++ b/score/crypto/src/backend/BUILD @@ -38,7 +38,7 @@ bool_flag( bool_flag( name = "score_crypto_score_primula_enabled", - build_setting_default = False, + build_setting_default = True, visibility = ["//visibility:public"], ) diff --git a/score/crypto/src/backend/README.md b/score/crypto/src/backend/README.md index 6076cf022..6f2b0886e 100644 --- a/score/crypto/src/backend/README.md +++ b/score/crypto/src/backend/README.md @@ -48,7 +48,7 @@ Backend enable/disable is controlled via `bool_flag` targets. All flags are in | `score_crypto_pkcs11_backend_enabled` | `True` | `--//score/crypto/src/backend:score_crypto_pkcs11_backend_enabled=False` | | `score_crypto_score_backend_enabled` | `True` | `--//score/crypto/src/backend:score_crypto_score_backend_enabled=False` | | `score_crypto_score_openssl_enabled` | `True` | `--//score/crypto/src/backend:score_crypto_score_openssl_enabled=False` | -| `score_crypto_score_primula_enabled` | `False` | `--//score/crypto/src/backend:score_crypto_score_primula_enabled=True` | +| `score_crypto_score_primula_enabled` | `True` | `--//score/crypto/src/backend:score_crypto_score_primula_enabled=False` | `score_crypto_score_backend_enabled` is the master gate for the score provider Individual sub-backend flags (`score_crypto_score_openssl_enabled`, etc.) have diff --git a/score/crypto/src/backend/score_provider/BUILD b/score/crypto/src/backend/score_provider/BUILD index d2aad81d5..4389caefd 100644 --- a/score/crypto/src/backend/score_provider/BUILD +++ b/score/crypto/src/backend/score_provider/BUILD @@ -56,7 +56,12 @@ cc_library( "//score/crypto/src/daemon/provider/score_provider:score_backend_adapter", "//score/crypto/src/backend/score_provider/openssl:openssl_backend_define", # To add a new score backend: add its *_backend_define dep here (step 3). - ], + ] + select({ + "//score/crypto/src/backend:primula_backend_active": [ + "//score/crypto/src/backend/score_provider/iav_primula:primula_backend_define", + ], + "//conditions:default": [], + }), ) # Heavy: aggregates all active sub-backend adapter targets. @@ -72,5 +77,10 @@ cc_library( deps = [ "//score/crypto/src/backend/score_provider/openssl:openssl_backend", # To add a new score backend: add its *_backend dep here (step 4). - ], + ] + select({ + "//score/crypto/src/backend:primula_backend_active": [ + "//score/crypto/src/backend/score_provider/iav_primula:primula_backend", + ], + "//conditions:default": [], + }), ) diff --git a/score/crypto/src/backend/score_provider/active_backends_list.hpp b/score/crypto/src/backend/score_provider/active_backends_list.hpp index 0a960159f..5cfcf15e6 100644 --- a/score/crypto/src/backend/score_provider/active_backends_list.hpp +++ b/score/crypto/src/backend/score_provider/active_backends_list.hpp @@ -25,7 +25,7 @@ #endif #ifdef SCORE_BACKEND_PRIMULA_ENABLED -#include "score/crypto/src/backend/score_provider/primula/primula_backend_adapter.hpp" +#include "score/crypto/src/backend/score_provider/iav_primula/primula_backend_adapter.hpp" #endif namespace score::crypto::backend::score_provider diff --git a/score/crypto/src/backend/score_provider/iav_primula/BUILD b/score/crypto/src/backend/score_provider/iav_primula/BUILD new file mode 100644 index 000000000..844f6c2f4 --- /dev/null +++ b/score/crypto/src/backend/score_provider/iav_primula/BUILD @@ -0,0 +1,39 @@ +load("@rules_cc//cc:defs.bzl", "cc_library") + +cc_library( + name = "primula_backend_adapter", + srcs = ["primula_backend_adapter.cpp"], + hdrs = ["primula_backend_adapter.hpp"], + target_compatible_with = select({ + "//score/crypto/src/backend:primula_backend_active": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + visibility = ["//score/crypto/src/backend/score_provider:__pkg__"], + deps = [ + "//score/crypto/src/daemon/provider/score_provider:score_backend_adapter", + "//score/crypto/src/daemon/provider/score_provider:provider_iav_primula_library", + ], +) + +cc_library( + name = "primula_backend_define", + defines = ["SCORE_BACKEND_PRIMULA_ENABLED=1"], + target_compatible_with = select({ + "//score/crypto/src/backend:primula_backend_active": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + visibility = [ + "//score/crypto/src/backend:__pkg__", + "//score/crypto/src/backend/score_provider:__pkg__", + ], +) + +cc_library( + name = "primula_backend", + target_compatible_with = select({ + "//score/crypto/src/backend:primula_backend_active": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + visibility = ["//score/crypto/src/backend/score_provider:__pkg__"], + deps = [":primula_backend_adapter", ":primula_backend_define"], +) diff --git a/score/crypto/src/backend/score_provider/iav_primula/primula_backend_adapter.cpp b/score/crypto/src/backend/score_provider/iav_primula/primula_backend_adapter.cpp new file mode 100644 index 000000000..94fd5711a --- /dev/null +++ b/score/crypto/src/backend/score_provider/iav_primula/primula_backend_adapter.cpp @@ -0,0 +1,37 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "primula_backend_adapter.hpp" + +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/iav_primula_provider.hpp" + +namespace score::crypto::backend::score_provider::primula +{ + +daemon::provider::score_provider::ProviderCreator PrimulaBackendAdapter::GetProviderCreator() const +{ + using namespace daemon::provider::score_provider; + + return ProviderCreator{ + .backend_id = "primula", + .backend_name = "PRIMULA", + // IAV-Primula provides post-quantum algorithms only. Mark it as SPECIALIZED + // so that it is not selected for generic SOFTWARE algorithms such as SHA-256 + // or HMAC, which are provided by OpenSSL. + .provider_type = "SPECIALIZED", + .create_provider = []() -> std::unique_ptr { + return std::make_unique(); + }}; +} + +} // namespace score::crypto::backend::score_provider::primula diff --git a/score/crypto/src/backend/score_provider/iav_primula/primula_backend_adapter.hpp b/score/crypto/src/backend/score_provider/iav_primula/primula_backend_adapter.hpp new file mode 100644 index 000000000..93ce40e4c --- /dev/null +++ b/score/crypto/src/backend/score_provider/iav_primula/primula_backend_adapter.hpp @@ -0,0 +1,62 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file primula_backend_adapter.hpp +/// @brief Backend adapter for the IAV-Primula score provider. + +#ifndef SCORE_CRYPTO_SRC_BACKEND_PROVIDER_IAV_PRIMULA_ADAPTER_HPP +#define SCORE_CRYPTO_SRC_BACKEND_PROVIDER_IAV_PRIMULA_ADAPTER_HPP + +#include "score/crypto/src/daemon/provider/score_provider/score_backend_adapter.hpp" + +namespace score::crypto::backend::score_provider::primula +{ + +/// @brief IAV-Primula backend adapter for the score provider family. +/// +/// Provides factory creation metadata for the IAV-Primula post-quantum +/// crypto backend. This adapter is included at compile time via +/// backend/score_provider/active_backends_list.hpp when the Primula backend +/// is enabled in the Bazel configuration. +/// +/// The IAV-Primula backend implementation lives in: +/// - daemon/provider/score_provider/iav_primula/iav_primula_provider.* +/// - daemon/provider/score_provider/iav_primula/operations/* +/// +/// This adapter provides backend metadata and creates the corresponding +/// provider instance. Cryptographic operations are implemented by the +/// IAV-Primula provider and its handlers. +class PrimulaBackendAdapter final : public daemon::provider::score_provider::IBackendProviderAdapter +{ + public: + PrimulaBackendAdapter() = default; + ~PrimulaBackendAdapter() override = default; + + PrimulaBackendAdapter(const PrimulaBackendAdapter&) = delete; + PrimulaBackendAdapter& operator=(const PrimulaBackendAdapter&) = delete; + PrimulaBackendAdapter(PrimulaBackendAdapter&&) = delete; + PrimulaBackendAdapter& operator=(PrimulaBackendAdapter&&) = delete; + + /// @brief Get the provider creator for the IAV-Primula backend. + /// + /// Returns: + /// - backend_id: "primula" + /// - backend_name: "PRIMULA" + /// - provider_type: "SPECIALIZED" + /// - create_provider: constructs and returns an IavPrimulaProvider + [[nodiscard]] daemon::provider::score_provider::ProviderCreator GetProviderCreator() const override; +}; + +} // namespace score::crypto::backend::score_provider::primula + +#endif // SCORE_CRYPTO_SRC_BACKEND_PROVIDER_IAV_PRIMULA_ADAPTER_HPP diff --git a/score/crypto/src/daemon/common/BUILD b/score/crypto/src/daemon/common/BUILD index 1cfebd98d..5ffa19f33 100644 --- a/score/crypto/src/daemon/common/BUILD +++ b/score/crypto/src/daemon/common/BUILD @@ -46,6 +46,9 @@ cc_library( "//score/crypto/src/daemon/key_management:key_management_operations", "//score/crypto/src/daemon/provider/handler:hash_handler_operations", "//score/crypto/src/daemon/provider/handler:mac_handler_operations", + "//score/crypto/src/daemon/provider/handler:sign_handler_operations", + "//score/crypto/src/daemon/provider/handler:verify_handler_operations", + "//score/crypto/src/daemon/provider/handler:kem_handler_operations", "@score_baselibs//score/mw/log", ], ) diff --git a/score/crypto/src/daemon/common/actors.hpp b/score/crypto/src/daemon/common/actors.hpp index bd7b3e417..06735c7f1 100644 --- a/score/crypto/src/daemon/common/actors.hpp +++ b/score/crypto/src/daemon/common/actors.hpp @@ -27,6 +27,9 @@ inline constexpr OperationActor OP_ACTOR_PROVIDER = 3; inline constexpr OperationActor OP_ACTOR_HASH_HANDLER = 4; inline constexpr OperationActor OP_ACTOR_KEY_MANAGEMENT = 5; inline constexpr OperationActor OP_ACTOR_MAC_HANDLER = 6; +inline constexpr OperationActor OP_ACTOR_SIGN_HANDLER = 7; +inline constexpr OperationActor OP_ACTOR_VERIFY_HANDLER = 8; +inline constexpr OperationActor OP_ACTOR_KEM_HANDLER = 9; // Starting point for custom actors inline constexpr OperationActor CUSTOM_ACTOR_START = 1 << (std::numeric_limits::digits - 1); diff --git a/score/crypto/src/daemon/common/algorithm_info.hpp b/score/crypto/src/daemon/common/algorithm_info.hpp index 1c8c62bcf..6c45fb5f4 100644 --- a/score/crypto/src/daemon/common/algorithm_info.hpp +++ b/score/crypto/src/daemon/common/algorithm_info.hpp @@ -14,7 +14,9 @@ #ifndef SCORE_CRYPTO_SRC_DAEMON_COMMON_ALGORITHM_INFO_HPP #define SCORE_CRYPTO_SRC_DAEMON_COMMON_ALGORITHM_INFO_HPP +#include #include +#include #include #include @@ -31,14 +33,14 @@ struct HashAlgorithmInfo std::size_t digest_size; ///< Output size in bytes }; -inline constexpr HashAlgorithmInfo kHashAlgorithms[] = { +inline constexpr std::array kHashAlgorithms{{ {"SHA256", 32U}, {"SHA384", 48U}, {"SHA512", 64U}, {"SHA224", 28U}, {"SHA1", 20U}, {"MD5", 16U}, -}; +}}; /// @brief Look up digest size by algorithm name. /// @return digest size in bytes, or std::nullopt if unknown. @@ -64,11 +66,11 @@ struct MacAlgorithmInfo std::size_t mac_size; ///< Output tag size in bytes }; -inline constexpr MacAlgorithmInfo kMacAlgorithms[] = { +inline constexpr std::array kMacAlgorithms = {{ {"HMAC-SHA256", 32U}, {"HMAC-SHA384", 48U}, {"HMAC-SHA512", 64U}, -}; +}}; /// @brief Look up MAC output size by algorithm name. /// @return MAC size in bytes, or std::nullopt if unknown. @@ -94,7 +96,72 @@ struct KeyAlgorithmInfo std::size_t key_size; ///< Default key size in bytes }; -inline constexpr KeyAlgorithmInfo kKeyAlgorithms[] = { +// --------------------------------------------------------------------------- +// Post-quantum algorithm properties +// --------------------------------------------------------------------------- + +/// @brief Identifies the operation family implemented by a PQC algorithm. +enum class PqcAlgorithmKind : std::uint8_t +{ + kSignature, + kKem, +}; + +/// @brief Fixed-size properties for standardized PQC parameter sets. +/// +/// The sizes describe the byte representation used at the provider boundary. +/// The provider remains responsible for validating the actual encoding. +struct PqcAlgorithmInfo +{ + std::string_view name; ///< Standardized algorithm identifier. + PqcAlgorithmKind kind; ///< Signature or KEM algorithm. + std::size_t public_key_size; ///< Public key size in bytes. + std::size_t private_key_size; ///< Private key size in bytes. + std::size_t signature_or_ciphertext_size; ///< Signature or ciphertext size in bytes; zero when not applicable. + std::size_t shared_secret_size; ///< Shared-secret size in bytes; zero for signature algorithms. +}; + +inline constexpr std::array kPqcAlgorithms = {{ + // ML-DSA: public key, private key, and signature sizes from FIPS 204. + {"ML-DSA-44", PqcAlgorithmKind::kSignature, 1312U, 2560U, 2420U, 0U}, + {"ML-DSA-65", PqcAlgorithmKind::kSignature, 1952U, 4032U, 3309U, 0U}, + {"ML-DSA-87", PqcAlgorithmKind::kSignature, 2592U, 4896U, 4627U, 0U}, + + // ML-KEM: public key, private key, ciphertext, and shared-secret sizes + // from FIPS 203. + {"ML-KEM-512", PqcAlgorithmKind::kKem, 800U, 1632U, 768U, 32U}, + {"ML-KEM-768", PqcAlgorithmKind::kKem, 1184U, 2400U, 1088U, 32U}, + {"ML-KEM-1024", PqcAlgorithmKind::kKem, 1568U, 3168U, 1568U, 32U}, +}}; + +/// @brief Look up a standardized PQC algorithm by its textual identifier. +[[nodiscard]] inline constexpr std::optional LookupPqcAlgorithm(std::string_view algorithm) noexcept +{ + for (const auto& entry : kPqcAlgorithms) + { + if (entry.name == algorithm) + { + return entry; + } + } + return std::nullopt; +} + +/// @brief Return whether the identifier names a PQC signature algorithm. +[[nodiscard]] inline constexpr bool IsPqcSignatureAlgorithm(std::string_view algorithm) noexcept +{ + const auto info = LookupPqcAlgorithm(algorithm); + return info.has_value() && info->kind == PqcAlgorithmKind::kSignature; +} + +/// @brief Return whether the identifier names a PQC KEM algorithm. +[[nodiscard]] inline constexpr bool IsPqcKemAlgorithm(std::string_view algorithm) noexcept +{ + const auto info = LookupPqcAlgorithm(algorithm); + return info.has_value() && info->kind == PqcAlgorithmKind::kKem; +} + +inline constexpr std::array kKeyAlgorithms = {{ {"HMAC-SHA256", 32U}, {"HMAC-SHA384", 48U}, {"HMAC-SHA512", 64U}, @@ -106,7 +173,7 @@ inline constexpr KeyAlgorithmInfo kKeyAlgorithms[] = { {"AES-256-GCM", 32U}, {"AES-128-CMAC", 16U}, {"AES-256-CMAC", 32U}, -}; +}}; /// @brief Look up default key size by algorithm name. /// @return key size in bytes, or std::nullopt if unknown. diff --git a/score/crypto/src/daemon/common/operation_names.hpp b/score/crypto/src/daemon/common/operation_names.hpp index c553f747f..721150a68 100644 --- a/score/crypto/src/daemon/common/operation_names.hpp +++ b/score/crypto/src/daemon/common/operation_names.hpp @@ -31,8 +31,8 @@ /// @endcode /// /// ### Design notes -/// - Header-only: all functions are constexpr, no runtime tables. -/// - Covers all first-party actors and their operations. +/// - Header-only: lookup functions are constexpr and do not use runtime tables. +/// - Covers the operation namespaces currently registered by this component. /// - Falls back to "" / "" for future or custom values, /// while still printing the numeric ids so nothing is lost. @@ -42,7 +42,10 @@ // Operation constants — these headers only depend on types.hpp (no circular risk). #include "score/crypto/src/daemon/key_management/interfaces/key_management_operations.hpp" #include "score/crypto/src/daemon/provider/handler/operations/hash_handler_operations.hpp" +#include "score/crypto/src/daemon/provider/handler/operations/kem_handler_operations.hpp" #include "score/crypto/src/daemon/provider/handler/operations/mac_handler_operations.hpp" +#include "score/crypto/src/daemon/provider/handler/operations/sign_handler_operations.hpp" +#include "score/crypto/src/daemon/provider/handler/operations/verify_handler_operations.hpp" #include "score/mw/log/logging.h" #include @@ -52,6 +55,7 @@ namespace score::crypto::daemon::common { /// @brief Returns the symbolic name for a registered OperationActor value. +/// @return Symbolic actor name, or "" for unknown actors. constexpr std::string_view ActorName(OperationActor actor) noexcept { switch (actor) @@ -68,6 +72,12 @@ constexpr std::string_view ActorName(OperationActor actor) noexcept return "KEY_MGMT"; case actors::OP_ACTOR_MAC_HANDLER: return "MAC_HANDLER"; + case actors::OP_ACTOR_SIGN_HANDLER: + return "SIGN_HANDLER"; + case actors::OP_ACTOR_VERIFY_HANDLER: + return "VERIFY_HANDLER"; + case actors::OP_ACTOR_KEM_HANDLER: + return "KEM_HANDLER"; default: return ""; } @@ -77,6 +87,8 @@ constexpr std::string_view ActorName(OperationActor actor) noexcept /// /// The actor context is required because the same action integer has different meanings /// across actors (e.g., action=1 is CTX_CREATE for MEDIATOR but HASH_INIT for HASH_HANDLER). +/// @return Symbolic operation name, or an actor-specific unknown-operation marker +/// if the action is not registered. constexpr std::string_view ActionName(OperationActor actor, OperationAction action) noexcept { // Mediator action constants (mediator_operations.hpp cannot be included here without @@ -144,6 +156,57 @@ constexpr std::string_view ActionName(OperationActor actor, OperationAction acti return ""; } + case actors::OP_ACTOR_SIGN_HANDLER: + switch (action) + { + case provider::handler::sign_handler_operations::SIGN_INIT: + return "SIGN_INIT"; + case provider::handler::sign_handler_operations::SIGN_UPDATE: + return "SIGN_UPDATE"; + case provider::handler::sign_handler_operations::SIGN_FINALIZE: + return "SIGN_FINALIZE"; + case provider::handler::sign_handler_operations::SIGN_SS: + return "SIGN_SS"; + case provider::handler::sign_handler_operations::SIGN_GET_SIGNATURE_SIZE: + return "SIGN_GET_SIGNATURE_SIZE"; + case provider::handler::sign_handler_operations::SIGN_RESET: + return "SIGN_RESET"; + default: + return ""; + } + + case actors::OP_ACTOR_VERIFY_HANDLER: + switch (action) + { + case provider::handler::verify_handler_operations::VERIFY_INIT: + return "VERIFY_INIT"; + case provider::handler::verify_handler_operations::VERIFY_UPDATE: + return "VERIFY_UPDATE"; + case provider::handler::verify_handler_operations::VERIFY_FINALIZE: + return "VERIFY_FINALIZE"; + case provider::handler::verify_handler_operations::VERIFY_SS: + return "VERIFY_SS"; + case provider::handler::verify_handler_operations::VERIFY_RESET: + return "VERIFY_RESET"; + default: + return ""; + } + + case actors::OP_ACTOR_KEM_HANDLER: + switch (action) + { + case provider::handler::kem_handler_operations::KEM_KEYGEN: + return "KEM_KEYGEN"; + case provider::handler::kem_handler_operations::KEM_ENCAPSULATE: + return "KEM_ENCAPSULATE"; + case provider::handler::kem_handler_operations::KEM_DECAPSULATE: + return "KEM_DECAPSULATE"; + case provider::handler::kem_handler_operations::KEM_RESET: + return "KEM_RESET"; + default: + return ""; + } + case actors::OP_ACTOR_KEY_MANAGEMENT: switch (action) { diff --git a/score/crypto/src/daemon/common/types.hpp b/score/crypto/src/daemon/common/types.hpp index 9f3bdfdf0..f484aa4a0 100644 --- a/score/crypto/src/daemon/common/types.hpp +++ b/score/crypto/src/daemon/common/types.hpp @@ -41,6 +41,9 @@ using MediatorId = std::string; // ProviderName: Human-readable identifier used at configuration and setup time using ProviderName = std::string; +/// @brief Configuration name identifying the IAV-Primula provider. +inline const ProviderName kProviderNameIavPrimula{"IAV_PRIMULA"}; + // ProviderId: Numeric identifier assigned at runtime by ProviderManager using ProviderId = std::uint16_t; diff --git a/score/crypto/src/daemon/provider/handler/BUILD b/score/crypto/src/daemon/provider/handler/BUILD index 040b0fdb1..2e4a0a57e 100644 --- a/score/crypto/src/daemon/provider/handler/BUILD +++ b/score/crypto/src/daemon/provider/handler/BUILD @@ -99,3 +99,24 @@ cc_library( visibility = ["//:__subpackages__"], deps = ["//score/crypto/src/daemon/common"], ) + +cc_library( + name = "sign_handler_operations", + hdrs = ["operations/sign_handler_operations.hpp"], + visibility = ["//:__subpackages__"], + deps = ["//score/crypto/src/daemon/common"], +) + +cc_library( + name = "verify_handler_operations", + hdrs = ["operations/verify_handler_operations.hpp"], + visibility = ["//:__subpackages__"], + deps = ["//score/crypto/src/daemon/common"], +) + +cc_library( + name = "kem_handler_operations", + hdrs = ["operations/kem_handler_operations.hpp"], + visibility = ["//:__subpackages__"], + deps = ["//score/crypto/src/daemon/common"], +) diff --git a/score/crypto/src/daemon/provider/handler/operations/kem_handler_operations.hpp b/score/crypto/src/daemon/provider/handler/operations/kem_handler_operations.hpp new file mode 100644 index 000000000..9576cdbfc --- /dev/null +++ b/score/crypto/src/daemon/provider/handler/operations/kem_handler_operations.hpp @@ -0,0 +1,42 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file kem_handler_operations.hpp +/// @brief Operation identifiers for provider-neutral KEM handlers. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_HANDLER_KEM_HANDLER_OPERATIONS_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_HANDLER_KEM_HANDLER_OPERATIONS_HPP + +#include "score/crypto/src/daemon/common/types.hpp" +#include + +namespace score::crypto::daemon::provider::handler::kem_handler_operations +{ +/// @brief Generate a KEM key pair. +inline constexpr common::OperationAction KEM_KEYGEN = 1; +/// @brief Encapsulate a shared secret using a peer public key. +inline constexpr common::OperationAction KEM_ENCAPSULATE = 2; +/// @brief Decapsulate a ciphertext with the bound private key. +inline constexpr common::OperationAction KEM_DECAPSULATE = 3; +/// @brief Reset the KEM handler state. +inline constexpr common::OperationAction KEM_RESET = 4; + +/// @brief First operation identifier reserved for custom KEM operations. +/// +/// The highest bit separates custom operation identifiers from the +/// built-in KEM handler operations. +inline constexpr common::OperationAction KEM_CUSTOM_OP_START = + 1 << (std::numeric_limits::digits - 1); +} // namespace score::crypto::daemon::provider::handler::kem_handler_operations + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_HANDLER_KEM_HANDLER_OPERATIONS_HPP diff --git a/score/crypto/src/daemon/provider/handler/operations/sign_handler_operations.hpp b/score/crypto/src/daemon/provider/handler/operations/sign_handler_operations.hpp new file mode 100644 index 000000000..f8c67e070 --- /dev/null +++ b/score/crypto/src/daemon/provider/handler/operations/sign_handler_operations.hpp @@ -0,0 +1,46 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file sign_handler_operations.hpp +/// @brief Operation identifiers for provider-neutral signature handlers. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_HANDLER_SIGN_HANDLER_OPERATIONS_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_HANDLER_SIGN_HANDLER_OPERATIONS_HPP + +#include "score/crypto/src/daemon/common/types.hpp" +#include + +namespace score::crypto::daemon::provider::handler::sign_handler_operations +{ +/// @brief Initialize a streaming signature operation. +inline constexpr common::OperationAction SIGN_INIT = 1; +/// @brief Add a message fragment to the signature operation. +inline constexpr common::OperationAction SIGN_UPDATE = 2; +/// @brief Finalize a streaming signature operation. +inline constexpr common::OperationAction SIGN_FINALIZE = 3; +/// @brief Sign a complete message in one operation. +inline constexpr common::OperationAction SIGN_SS = 4; +/// @brief Query the signature size for the selected algorithm. +inline constexpr common::OperationAction SIGN_GET_SIGNATURE_SIZE = 5; +/// @brief Reset the signature operation state. +inline constexpr common::OperationAction SIGN_RESET = 6; + +/// @brief First operation identifier reserved for custom signature operations. +/// +/// The highest bit separates custom operation identifiers from the +/// built-in signature handler operations. +inline constexpr common::OperationAction SIGN_CUSTOM_OP_START = + 1 << (std::numeric_limits::digits - 1); +} // namespace score::crypto::daemon::provider::handler::sign_handler_operations + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_HANDLER_SIGN_HANDLER_OPERATIONS_HPP diff --git a/score/crypto/src/daemon/provider/handler/operations/verify_handler_operations.hpp b/score/crypto/src/daemon/provider/handler/operations/verify_handler_operations.hpp new file mode 100644 index 000000000..751942571 --- /dev/null +++ b/score/crypto/src/daemon/provider/handler/operations/verify_handler_operations.hpp @@ -0,0 +1,44 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file verify_handler_operations.hpp +/// @brief Operation identifiers for provider-neutral signature verification handlers. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_HANDLER_VERIFY_HANDLER_OPERATIONS_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_HANDLER_VERIFY_HANDLER_OPERATIONS_HPP + +#include "score/crypto/src/daemon/common/types.hpp" +#include + +namespace score::crypto::daemon::provider::handler::verify_handler_operations +{ +/// @brief Initialize a streaming verification operation. +inline constexpr common::OperationAction VERIFY_INIT = 1; +/// @brief Add a message fragment to the verification operation. +inline constexpr common::OperationAction VERIFY_UPDATE = 2; +/// @brief Verify a signature against the accumulated message. +inline constexpr common::OperationAction VERIFY_FINALIZE = 3; +/// @brief Verify a complete message in one operation. +inline constexpr common::OperationAction VERIFY_SS = 4; +/// @brief Reset the verification operation state. +inline constexpr common::OperationAction VERIFY_RESET = 5; + +/// @brief First operation identifier reserved for custom verification operations. +/// +/// The highest bit separates custom operation identifiers from the +/// built-in verification handler operations. +inline constexpr common::OperationAction VERIFY_CUSTOM_OP_START = + 1 << (std::numeric_limits::digits - 1); +} // namespace score::crypto::daemon::provider::handler::verify_handler_operations + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_HANDLER_VERIFY_HANDLER_OPERATIONS_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/BUILD b/score/crypto/src/daemon/provider/score_provider/BUILD index ee5ffaa6d..3ea2de572 100644 --- a/score/crypto/src/daemon/provider/score_provider/BUILD +++ b/score/crypto/src/daemon/provider/score_provider/BUILD @@ -58,6 +58,48 @@ cc_library( ], ) +cc_library( + name = "provider_iav_primula_library", + srcs = [ + "iav_primula/iav_primula_provider.cpp", + "iav_primula/operations/factory/iav_primula_handler_factory.cpp", + "iav_primula/key_management/iav_primula_key_factory.cpp", + "iav_primula/key_management/iav_primula_key_handler.cpp", + "iav_primula/operations/sign/iav_primula_sign_handler.cpp", + "iav_primula/operations/verify/iav_primula_verify_handler.cpp", + "iav_primula/operations/kem/iav_primula_kem_handler.cpp", + ], + hdrs = [ + "iav_primula/iav_primula_provider.hpp", + "iav_primula/operations/factory/iav_primula_handler_factory.hpp", + "iav_primula/key_management/iav_primula_key_factory.hpp", + "iav_primula/key_management/iav_primula_key_handler.hpp", + "iav_primula/operations/sign/iav_primula_sign_handler.hpp", + "iav_primula/operations/verify/iav_primula_verify_handler.hpp", + "iav_primula/operations/kem/iav_primula_kem_handler.hpp", + ], + target_compatible_with = select({ + "//score/crypto/src/backend:primula_backend_active": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + visibility = [ + "//score/crypto/src/backend/score_provider/iav_primula:__pkg__", + "//score/crypto/src/daemon/provider/score_provider:__subpackages__", + ], + deps = [ + "//score/crypto/src/daemon/common:algorithm_info", + "//score/crypto/src/daemon/key_management:key_management_headers", + "//score/crypto/src/daemon/provider/handler:crypto_handler_factory_headers", + "//score/crypto/src/daemon/provider/score_provider", + "//score/crypto/src/daemon/provider/score_provider/operations/factory:score_handler_factory", + "//score/crypto/src/daemon/provider/score_provider/operations/kem:score_kem_handler", + "//score/crypto/src/daemon/provider/score_provider/operations/sign:score_sign_handler", + "//score/crypto/src/daemon/provider/score_provider/operations/verify:score_verify_handler", + "//score/iav_primula:iav_primula_ffi_headers", + "//score/iav_primula:iav_primula_staticlib", + ], +) + # Top-level factory for the score interface family. cc_library( name = "score_provider_factory", diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/iav_primula_provider.cpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/iav_primula_provider.cpp new file mode 100644 index 000000000..6b77f6258 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/iav_primula_provider.cpp @@ -0,0 +1,75 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/iav_primula_provider.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_factory.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/factory/iav_primula_handler_factory.hpp" + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ + +bool IavPrimulaProvider::InitialiseBackend(const ProviderInitContext& ctx) +{ + const bool initialized = true; + if (initialized) + { + m_factory = std::make_shared(ctx.numeric_id); + } + return initialized; +} + +void IavPrimulaProvider::Shutdown() +{ + if (!IsInitialized()) + { + return; + } + + m_factory.reset(); + m_keyManagementService.reset(); + + // TODO implement cleanup of the Primula handler ressources on shutdown if required + + // Base class resets factory and flags. + ScoreProvider::Shutdown(); +} + +std::shared_ptr IavPrimulaProvider::GetKeyFactory() +{ + return m_factory; +} + +std::shared_ptr IavPrimulaProvider::GetKeySlotHandler( + const key_management::KeySlotConfig& config) +{ + // TODO: return Primula-specific key slot handler if supported. + return ScoreProvider::GetKeySlotHandler(config); +} + +void IavPrimulaProvider::SetKeyManagementService(std::shared_ptr service) +{ + m_keyManagementService = std::move(service); +} + +/// @brief Create the IAV-Primula-specific handler factory. +/// +/// The provider exposes only the generic handler-factory interface to the +/// daemon. PQC implementation details remain below that boundary. +std::shared_ptr IavPrimulaProvider::CreateHandlerFactory() +{ + return std::make_shared(m_factory, + nullptr, // TODO This needs to be a key slot handler for primula + m_keyManagementService); +} + +} // namespace score::crypto::daemon::provider::score_provider::iav_primula diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/iav_primula_provider.hpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/iav_primula_provider.hpp new file mode 100644 index 000000000..576d8b210 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/iav_primula_provider.hpp @@ -0,0 +1,65 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file iav_primula_provider.hpp +/// @brief IAV-Primula provider implementation for the score interface. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_PROVIDER_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_PROVIDER_HPP + +#include + +#include "score/crypto/src/daemon/provider/score_provider/score_provider.hpp" + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ + +/// @brief IAV-Primula is a provider for post-quantum cryptographic algorithms. +/// +/// Inherits ScoreProvider for provider lifecycle management and lazy handler +/// factory creation. Provides IAV-Primula-specific key management and +/// cryptographic operation handlers without exposing implementation details +/// to the daemon core. +class IavPrimulaProvider final : public ::score::crypto::daemon::provider::score_provider::ScoreProvider +{ + public: + IavPrimulaProvider() = default; + ~IavPrimulaProvider() override = default; + + IavPrimulaProvider(const IavPrimulaProvider&) = delete; + IavPrimulaProvider& operator=(const IavPrimulaProvider&) = delete; + IavPrimulaProvider(IavPrimulaProvider&&) = delete; + IavPrimulaProvider& operator=(IavPrimulaProvider&&) = delete; + + // --- IProvider lifecycle (IAV-Primula-specific) --- + void Shutdown() override; + [[nodiscard]] bool InitialiseBackend(const ProviderInitContext& ctx) override; + + // --- Key management capability --- + std::shared_ptr GetKeyFactory() override; + std::shared_ptr GetKeySlotHandler( + const key_management::KeySlotConfig& config) override; + void SetKeyManagementService(std::shared_ptr service) override; + + protected: + /// @brief Creates the IAV-Primula-specific handler factory. + [[nodiscard]] std::shared_ptr CreateHandlerFactory() override; + + private: + std::shared_ptr m_factory; + std::shared_ptr m_keyManagementService; +}; + +} // namespace score::crypto::daemon::provider::score_provider::iav_primula + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_PROVIDER_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_factory.cpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_factory.cpp new file mode 100644 index 000000000..7fa31f4da --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_factory.cpp @@ -0,0 +1,122 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_factory.hpp" +#include "score/crypto/src/daemon/common/algorithm_info.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp" +#include "score/iav_primula/include/iav_primula_ffi.h" + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ +namespace +{ +/// @brief Map a PQC algorithm identifier to the IAV-Primula enum value. +/// +/// @return The corresponding IAV-Primula algorithm, or +/// kUnsupportedAlgorithm if the identifier is unknown. +Expected Algorithm(common::AlgorithmId algorithmId) +{ + auto algorithmDescription = std::string_view{algorithmId.data(), algorithmId.size()}; + if (algorithmDescription == "ML-DSA-44") + { + return IavAlgorithmMlDsa44; + } + if (algorithmDescription == "ML-DSA-65") + { + return IavAlgorithmMlDsa65; + } + if (algorithmDescription == "ML-DSA-87") + { + return IavAlgorithmMlDsa87; + } + if (algorithmDescription == "ML-KEM-512") + { + return IavAlgorithmMlKem512; + } + if (algorithmDescription == "ML-KEM-768") + { + return IavAlgorithmMlKem768; + } + if (algorithmDescription == "ML-KEM-1024") + { + return IavAlgorithmMlKem1024; + } + return make_unexpected(common::DaemonErrorCode::kUnsupportedAlgorithm); +} +} // namespace + +Expected IavPrimulaKeyFactory::GenerateKey( + const key_management::KeyGenerationRequest& r) +{ + auto info = common::LookupPqcAlgorithm(std::string_view{r.algorithm.data(), r.algorithm.size()}); + if (!info || + ((info->kind != common::PqcAlgorithmKind::kSignature) && (info->kind != common::PqcAlgorithmKind::kKem))) + { + return make_unexpected(common::DaemonErrorCode::kUnsupportedAlgorithm); + } + + auto algorithm = Algorithm(r.algorithm); + if (!algorithm.has_value()) + { + return make_unexpected(algorithm.error()); + } + + iav_primula_key_handle* key = nullptr; + const auto generate_status = (info->kind == common::PqcAlgorithmKind::kKem) + ? iav_kem_keypair_generate(algorithm.value(), &key) + : iav_keypair_generate(algorithm.value(), &key); + if (generate_status != IavStatusOk || key == nullptr) + { + return make_unexpected(common::DaemonErrorCode::kOperationFailed); + } + + std::vector pub(info->public_key_size); + std::size_t n = pub.size(); + const auto export_status = (info->kind == common::PqcAlgorithmKind::kKem) + ? iav_kem_public_key_export(key, pub.data(), &n) + : iav_public_key_export(key, pub.data(), &n); + if (export_status != IavStatusOk || n != pub.size()) + { + iav_key_destroy(key); + return make_unexpected(common::DaemonErrorCode::kOperationFailed); + } + + key_management::ProviderKeyHandle h{}; + h.opaque_id = reinterpret_cast(key); + h.provider_id = m_provider_id; + h.permissions = r.permissions; + h.is_asymmetric = true; + h.algorithm = r.algorithm; + h.key_size = info->private_key_size; + return std::make_shared(key, std::move(pub), h); +} + +Expected IavPrimulaKeyFactory::ImportKey( + const key_management::KeyImportRequest& r) +{ + auto info = common::LookupPqcAlgorithm(std::string_view{r.algorithm.data(), r.algorithm.size()}); + if (!info || + ((info->kind != common::PqcAlgorithmKind::kSignature) && (info->kind != common::PqcAlgorithmKind::kKem)) || + !r.key_data || (r.key_data_size != info->public_key_size)) + return make_unexpected(common::DaemonErrorCode::kInvalidArgument); + + std::vector pub(r.key_data, r.key_data + r.key_data_size); + key_management::ProviderKeyHandle h{}; + h.provider_id = m_provider_id; + h.permissions = r.permissions; + h.is_asymmetric = true; + h.algorithm = r.algorithm; + h.key_size = info->public_key_size; + return std::make_shared(nullptr, std::move(pub), h); +} +} // namespace score::crypto::daemon::provider::score_provider::iav_primula diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_factory.hpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_factory.hpp new file mode 100644 index 000000000..d2e159b15 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_factory.hpp @@ -0,0 +1,57 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +/// @file iav_primula_key_factory.hpp +/// @brief Key factory for IAV-Primula provider keys. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_KEY_FACTORY_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_KEY_FACTORY_HPP + +#include "score/crypto/src/daemon/key_management/interfaces/i_key_factory.hpp" + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ + +/// @brief IAV-Primula key factory for post-quantum algorithms. +/// +/// Creates and imports key handlers for the supported ML-DSA and ML-KEM +/// parameter sets. Each generated key is associated with the provider ID +/// supplied during construction. +class IavPrimulaKeyFactory final : public key_management::IKeyFactory +{ + public: + /// @brief Create a key factory for the specified provider instance. + /// + /// @param id Numeric identifier assigned to the provider. + explicit IavPrimulaKeyFactory(common::ProviderId providerId) : m_provider_id(providerId) {} + + /// @brief Generate an IAV-Primula key pair. + /// + /// Supports the ML-DSA and ML-KEM parameter sets defined by the provider. + /// The returned handler owns the native key handle and the exported public + /// key material. + [[nodiscard]] Expected GenerateKey( + const key_management::KeyGenerationRequest&) override; + + /// @brief Import public key material for an IAV-Primula algorithm. + /// + /// Supports public keys for the ML-DSA and ML-KEM parameter sets defined by + /// the provider. The key material is copied into the returned key handler. + [[nodiscard]] Expected ImportKey( + const key_management::KeyImportRequest&) override; + + private: + common::ProviderId m_provider_id{}; ///< Numeric identifier of the owning provider instance. +}; +} // namespace score::crypto::daemon::provider::score_provider::iav_primula + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_KEY_FACTORY_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.cpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.cpp new file mode 100644 index 000000000..8ba170b79 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.cpp @@ -0,0 +1,77 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp" +#include "score/crypto/src/api/common/types.hpp" +#include + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ +IavPrimulaKeyHandler::IavPrimulaKeyHandler(iav_primula_key_handle* key, + std::vector pub, + const key_management::ProviderKeyHandle& handle) noexcept + : m_native_key{key}, m_public_key{std::move(pub)}, m_handle{handle} +{ +} + +IavPrimulaKeyHandler::~IavPrimulaKeyHandler() +{ + static_cast(Release()); +} + +const key_management::ProviderKeyHandle& IavPrimulaKeyHandler::GetHandle() const noexcept +{ + return m_handle; +} + +common::ProviderId IavPrimulaKeyHandler::GetProviderId() const noexcept +{ + return m_handle.provider_id; +} + +Expected IavPrimulaKeyHandler::Release() +{ + if (!m_released) + { + // Release the native key handle and wipe cached key material exactly once. + if (m_native_key != nullptr) + { + iav_key_destroy(m_native_key); + } + m_native_key = nullptr; + std::fill(m_public_key.begin(), m_public_key.end(), 0U); + m_public_key.clear(); + m_released = true; + } + return std::monostate{}; +} + +Expected IavPrimulaKeyHandler::Export() const +{ + // Export only the cached public key after checking permissions and release state. + if (!score::crypto::HasPermission(m_handle.permissions, score::crypto::KeyOperationPermission::kExport) || + m_released) + { + return make_unexpected(common::DaemonErrorCode::kKeyOperationNotPermitted); + } + + key_management::SecureKeyBytes out(m_public_key.size()); + std::copy(m_public_key.begin(), m_public_key.end(), out.bytes.begin()); + return out; +} + +const std::uint8_t* IavPrimulaKeyHandler::GetPublicKey(std::size_t& size) const noexcept +{ + size = m_released ? 0U : m_public_key.size(); + return size == 0U ? nullptr : m_public_key.data(); +} +} // namespace score::crypto::daemon::provider::score_provider::iav_primula diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp new file mode 100644 index 000000000..69bfc5dbd --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp @@ -0,0 +1,90 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +/// @file iav_primula_key_handler.hpp +/// @brief Key handler for IAV-Primula provider keys. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_KEY_HANDLER_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_KEY_HANDLER_HPP + +#include "score/crypto/src/daemon/key_management/interfaces/i_key_handler.hpp" +#include "score/iav_primula/include/iav_primula_ffi.h" +#include + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ + +/// @brief Key handler for IAV-Primula post-quantum keys. +/// +/// Owns an optional native IAV-Primula key handle and a cached copy of the +/// public key. The native handle is destroyed and the cached key material is +/// cleared when Release() is called or the handler is destroyed. +/// +/// Imported public keys do not have a native key handle. +class IavPrimulaKeyHandler final : public key_management::IKeyHandler +{ + public: + /// @brief Create a key handler for an IAV-Primula key. + /// + /// The handler takes ownership of native_key and takes a copy of the + /// provider key metadata. native_key may be nullptr for imported public + /// keys. + IavPrimulaKeyHandler(iav_primula_key_handle* native_key, + std::vector public_key, + const key_management::ProviderKeyHandle& handle) noexcept; + ~IavPrimulaKeyHandler() override; + IavPrimulaKeyHandler(const IavPrimulaKeyHandler&) = delete; + IavPrimulaKeyHandler& operator=(const IavPrimulaKeyHandler&) = delete; + IavPrimulaKeyHandler(const IavPrimulaKeyHandler&&) = delete; + IavPrimulaKeyHandler& operator=(const IavPrimulaKeyHandler&&) = delete; + /// @brief Return the provider metadata associated with the key. + /// + /// The returned metadata contains the provider ID, algorithm, permissions, + /// and key properties. It does not expose the native IAV-Primula key handle. + [[nodiscard]] const key_management::ProviderKeyHandle& GetHandle() const noexcept override; + /// @brief Release the native key handle and cached public key material. + /// + /// This operation is idempotent and can safely be called more than once. + [[nodiscard]] Expected Release() override; + /// @brief Export the cached public key. + /// + /// Export requires the corresponding key permission and is not allowed + /// after the key has been released. + [[nodiscard]] Expected Export() const override; + /// @brief Return the numeric identifier of the owning provider instance. + /// + /// The identifier is stored in the provider key metadata and is used to + /// associate the key with the provider that created or imported it. + [[nodiscard]] common::ProviderId GetProviderId() const noexcept override; + /// @brief Return the native IAV-Primula key handle. + /// + /// Returns nullptr when the key was imported as public key material or has + /// already been released. The returned handle remains owned by this handler. + [[nodiscard]] iav_primula_key_handle* GetNativeHandle() const noexcept + { + return m_native_key; + } + /// @brief Return a non-owning pointer to the cached public key. + /// + /// The pointer remains valid until the key is released or the handler is + /// destroyed. Returns nullptr and sets size to zero after release. + [[nodiscard]] const std::uint8_t* GetPublicKey(std::size_t& size) const noexcept; + + private: + iav_primula_key_handle* m_native_key; ///< Owned native key handle, or nullptr for public-only keys. + std::vector m_public_key; ///< Cached public key material. + key_management::ProviderKeyHandle m_handle; ///< Provider metadata associated with the key. + bool m_released{false}; ///< Whether the key material has already been released. +}; +} // namespace score::crypto::daemon::provider::score_provider::iav_primula + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_KEY_HANDLER_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/factory/iav_primula_handler_factory.cpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/factory/iav_primula_handler_factory.cpp new file mode 100644 index 000000000..08cda26d8 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/factory/iav_primula_handler_factory.cpp @@ -0,0 +1,87 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/factory/iav_primula_handler_factory.hpp" +#include "score/crypto/src/api/common/error_domain.hpp" +#include "score/crypto/src/daemon/common/algorithm_info.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/kem/iav_primula_kem_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/sign/iav_primula_sign_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/verify/iav_primula_verify_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/kem/kem_executor.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/sign/sign_executor.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/verify/verify_executor.hpp" + +#include +#include + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ + +namespace +{ +/// @brief Create a score error result for an unsupported algorithm. +/// +/// The returned result contains no handler and uses the +/// kUnsupportedAlgorithm error code. +::score::Result MakeUnsupportedAlgorithmError(const std::string& message) +{ + const ::score::result::Error error( + static_cast<::score::result::ErrorCode>(::score::crypto::CryptoErrorCode::kUnsupportedAlgorithm), + ::score::crypto::kCryptoErrorDomain, + message); + return ::score::Result(::score::unexpect, error); +} +} // namespace + +IavPrimulaHandlerFactory::IavPrimulaHandlerFactory(std::shared_ptr key_factory, + std::shared_ptr slot_handler, + key_management::KeyManagementService::Sptr km_service) + : ScoreHandlerFactory(std::move(key_factory), std::move(slot_handler), std::move(km_service)) +{ +} + +::score::Result IavPrimulaHandlerFactory::CreateSignHandler( + const common::AlgorithmId& algorithm) +{ + if (!common::IsPqcSignatureAlgorithm(algorithm)) + { + return MakeUnsupportedAlgorithmError("Algorithm is not a supported iavPrimula signature algorithm: " + + algorithm); + } + + return std::make_shared(std::make_unique(), algorithm); +} + +::score::Result IavPrimulaHandlerFactory::CreateVerifyHandler( + const common::AlgorithmId& algorithm) +{ + if (!common::IsPqcSignatureAlgorithm(algorithm)) + { + return MakeUnsupportedAlgorithmError("Algorithm is not a supported iavPrimula verification algorithm: " + + algorithm); + } + + return std::make_shared(std::make_unique(), algorithm); +} + +::score::Result IavPrimulaHandlerFactory::CreateKemHandler(const common::AlgorithmId& algorithm) +{ + if (!common::IsPqcKemAlgorithm(algorithm)) + { + return MakeUnsupportedAlgorithmError("Algorithm is not a supported iavPrimula KEM algorithm: " + algorithm); + } + + return std::make_shared(std::make_unique(), algorithm); +} + +} // namespace score::crypto::daemon::provider::score_provider::iav_primula diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/factory/iav_primula_handler_factory.hpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/factory/iav_primula_handler_factory.hpp new file mode 100644 index 000000000..b290f56e8 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/factory/iav_primula_handler_factory.hpp @@ -0,0 +1,76 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file iav_primula_handler_factory.hpp +/// @brief Handler factory for IAV-Primula operations. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_HANDLER_FACTORY_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_HANDLER_FACTORY_HPP + +#include "score/crypto/src/daemon/provider/score_provider/operations/factory/score_handler_factory.hpp" +#include "score/result/result.h" + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ + +/// @brief Factory for IAV-Primula SIGN, VERIFY, and KEM handlers. +/// +/// Validates the requested PQC algorithm and creates the corresponding +/// IAV-Primula handler with its provider-neutral operation executor. +/// Unsupported algorithm families result in kUnsupportedAlgorithm. +class IavPrimulaHandlerFactory final + : public ::score::crypto::daemon::provider::score_provider::operations::factory::ScoreHandlerFactory +{ + public: + /// @brief Create an IAV-Primula handler factory. + /// + /// @param key_factory Factory used for provider-specific key operations. + /// @param slot_handler Key-slot handler used for persistent key operations. + /// @param km_service Key-management service shared with the handlers. + IavPrimulaHandlerFactory(std::shared_ptr key_factory, + std::shared_ptr slot_handler, + key_management::KeyManagementService::Sptr km_service); + + ~IavPrimulaHandlerFactory() override = default; + + IavPrimulaHandlerFactory(const IavPrimulaHandlerFactory&) = delete; + IavPrimulaHandlerFactory& operator=(const IavPrimulaHandlerFactory&) = delete; + IavPrimulaHandlerFactory(IavPrimulaHandlerFactory&&) = delete; + IavPrimulaHandlerFactory& operator=(IavPrimulaHandlerFactory&&) = delete; + + protected: + /// @brief Create a handler for a supported ML-DSA signature algorithm. + /// + /// @return A signature handler, or kUnsupportedAlgorithm if the algorithm + /// is not an ML-DSA signature algorithm. + [[nodiscard]] ::score::Result<::score::crypto::daemon::provider::handler::Handler::Sptr> CreateSignHandler( + const common::AlgorithmId& algorithm) override; + + /// @brief Create a handler for a supported ML-DSA verification algorithm. + /// + /// @return A verification handler, or kUnsupportedAlgorithm if the + /// algorithm is not an ML-DSA signature algorithm. + [[nodiscard]] ::score::Result<::score::crypto::daemon::provider::handler::Handler::Sptr> CreateVerifyHandler( + const common::AlgorithmId& algorithm) override; + + /// @brief Create a handler for a supported ML-KEM algorithm. + /// + /// @return A KEM handler, or kUnsupportedAlgorithm if the algorithm is not + /// an ML-KEM algorithm. + [[nodiscard]] ::score::Result<::score::crypto::daemon::provider::handler::Handler::Sptr> CreateKemHandler( + const common::AlgorithmId& algorithm) override; +}; + +} // namespace score::crypto::daemon::provider::score_provider::iav_primula + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_HANDLER_FACTORY_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/kem/iav_primula_kem_handler.cpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/kem/iav_primula_kem_handler.cpp new file mode 100644 index 000000000..f7d77ee66 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/kem/iav_primula_kem_handler.cpp @@ -0,0 +1,151 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/kem/iav_primula_kem_handler.hpp" + +#include "score/crypto/src/daemon/common/algorithm_info.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/kem/kem_executor.hpp" + +#include +#include + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ + +IavPrimulaKemHandler::IavPrimulaKemHandler(std::unique_ptr executor, + common::AlgorithmId algorithm) + : ScoreKemHandler(std::move(executor), std::move(algorithm)) +{ +} + +Expected IavPrimulaKemHandler::GetAlgorithm() const noexcept +{ + if (m_algorithm == "ML-KEM-512") + { + return IavAlgorithmMlKem512; + } + if (m_algorithm == "ML-KEM-768") + { + return IavAlgorithmMlKem768; + } + if (m_algorithm == "ML-KEM-1024") + { + return IavAlgorithmMlKem1024; + } + return make_unexpected(common::DaemonErrorCode::kUnsupportedAlgorithm); +} + +Expected IavPrimulaKemHandler::InitializeContext( + const handler::InitializationParams& init_params) +{ + // Bind an optional IAV-Primula key. A key is required later for + // decapsulation, but not for key generation or encapsulation. + m_key = nullptr; + if (init_params.bound_key_handler != nullptr) + { + const auto* key = dynamic_cast(init_params.bound_key_handler); + if (key == nullptr) + { + return make_unexpected(common::DaemonErrorCode::kInvalidArgument); + } + m_key = key->GetNativeHandle(); + } + return {}; +} + +Expected IavPrimulaKemHandler::GenerateKeyPair() +{ + auto algorithm = GetAlgorithm(); + if (!algorithm.has_value()) + { + return make_unexpected(algorithm.error()); + } + + // Generate a temporary KEM key pair, export its public key, and release the + // native key handle before returning the public key. + iav_primula_key_handle* key = nullptr; + if (iav_kem_keypair_generate(algorithm.value(), &key) != IavStatusOk || key == nullptr) + { + return make_unexpected(common::DaemonErrorCode::kOperationFailed); + } + + const auto info = common::LookupPqcAlgorithm(m_algorithm); + std::vector public_key(info->public_key_size); + std::size_t length = public_key.size(); + const auto status = iav_kem_public_key_export(key, public_key.data(), &length); + iav_key_destroy(key); + if (status != IavStatusOk || length != public_key.size()) + { + return make_unexpected(common::DaemonErrorCode::kOperationFailed); + } + return common::ResponseParameters{common::OwnedBuffer{std::move(public_key)}}; +} + +Expected IavPrimulaKemHandler::Encapsulate( + const common::RequestParameter& request) +{ + const auto* public_key = std::get_if>(&request); + const auto info = common::LookupPqcAlgorithm(m_algorithm); + auto algorithm = GetAlgorithm(); + if ((public_key == nullptr) || !info.has_value() || !algorithm.has_value() || + (public_key->size() != info->public_key_size)) + { + return make_unexpected(common::DaemonErrorCode::kInvalidArgument); + } + + // Encapsulate a shared secret using the supplied public key. The response + // contains the ciphertext followed by the shared secret. + std::vector ciphertext(info->signature_or_ciphertext_size); + std::vector secret(info->shared_secret_size); + std::size_t ciphertext_length = ciphertext.size(); + std::size_t secret_length = secret.size(); + const auto status = iav_kem_encapsulate(algorithm.value(), + public_key->data(), + public_key->size(), + ciphertext.data(), + &ciphertext_length, + secret.data(), + &secret_length); + if ((status != IavStatusOk) || (ciphertext_length != ciphertext.size()) || (secret_length != secret.size())) + { + return make_unexpected(common::DaemonErrorCode::kOperationFailed); + } + return common::ResponseParameters{common::OwnedBuffer{std::move(ciphertext)}, + common::OwnedBuffer{std::move(secret)}}; +} + +Expected IavPrimulaKemHandler::Decapsulate( + const common::RequestParameter& request) +{ + const auto* ciphertext = std::get_if>(&request); + const auto info = common::LookupPqcAlgorithm(m_algorithm); + if ((m_key == nullptr) || (ciphertext == nullptr) || !info.has_value() || + (ciphertext->size() != info->signature_or_ciphertext_size)) + { + return make_unexpected(common::DaemonErrorCode::kInvalidArgument); + } + + // Decapsulate the ciphertext with the native key bound during context + // initialization and return the resulting shared secret. + std::vector secret(info->shared_secret_size); + std::size_t length = secret.size(); + const auto status = iav_kem_decapsulate(m_key, ciphertext->data(), ciphertext->size(), secret.data(), &length); + if ((status != IavStatusOk) || (length != secret.size())) + { + return make_unexpected(common::DaemonErrorCode::kOperationFailed); + } + return common::ResponseParameters{common::OwnedBuffer{std::move(secret)}}; +} + +} // namespace score::crypto::daemon::provider::score_provider::iav_primula diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/kem/iav_primula_kem_handler.hpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/kem/iav_primula_kem_handler.hpp new file mode 100644 index 000000000..09dcba415 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/kem/iav_primula_kem_handler.hpp @@ -0,0 +1,81 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file iav_primula_kem_handler.hpp +/// @brief IAV-Primula implementation of the KEM handler. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_KEM_HANDLER_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_KEM_HANDLER_HPP + +#include "score/crypto/src/daemon/provider/score_provider/operations/kem/score_kem_handler.hpp" +#include "score/iav_primula/include/iav_primula_ffi.h" + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ + +/// @brief IAV-Primula implementation of the provider-neutral KEM handler. +class IavPrimulaKemHandler final : public operations::kem::ScoreKemHandler +{ + public: + /// @brief Create an IAV-Primula KEM handler. + /// + /// Takes ownership of the operation executor and stores the selected + /// ML-KEM algorithm. + /// + /// @param executor Provider-neutral executor for KEM operations. + /// @param algorithm ML-KEM algorithm identifier. + IavPrimulaKemHandler(std::unique_ptr executor, common::AlgorithmId algorithm); + ~IavPrimulaKemHandler() override = default; + + IavPrimulaKemHandler(const IavPrimulaKemHandler&) = delete; + IavPrimulaKemHandler& operator=(const IavPrimulaKemHandler&) = delete; + IavPrimulaKemHandler(const IavPrimulaKemHandler&&) = delete; + IavPrimulaKemHandler& operator=(const IavPrimulaKemHandler&&) = delete; + + /// @brief Bind an optional IAV-Primula key to the operation context. + /// + /// A native key is required for decapsulation but not for key generation + /// or encapsulation. + /// + /// @param init_params Context initialization parameters, including an + /// optional bound key handler. + [[nodiscard]] Expected InitializeContext( + const handler::InitializationParams& init_params) override; + /// @brief Generate a KEM key pair and return its public key. + /// + /// The native private key is released before the operation returns. + [[nodiscard]] Expected GenerateKeyPair() override; + /// @brief Encapsulate a shared secret using a public key. + /// + /// The response contains the ciphertext followed by the shared secret. + /// + /// @param request Request containing the peer public key. + [[nodiscard]] Expected Encapsulate( + const common::RequestParameter& request) override; + /// @brief Decapsulate a ciphertext using the bound private key. + /// + /// @param request Request containing the ciphertext. + [[nodiscard]] Expected Decapsulate( + const common::RequestParameter& request) override; + + private: + /// @brief Map the configured algorithm to the corresponding IAV-Primula enum. + /// + /// @return The mapped algorithm, or kUnsupportedAlgorithm if unsupported. + [[nodiscard]] Expected GetAlgorithm() const noexcept; + iav_primula_key_handle* m_key{nullptr}; ///< Non-owning handle borrowed from the bound key handler. +}; + +} // namespace score::crypto::daemon::provider::score_provider::iav_primula + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_KEM_HANDLER_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/sign/iav_primula_sign_handler.cpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/sign/iav_primula_sign_handler.cpp new file mode 100644 index 000000000..80788b357 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/sign/iav_primula_sign_handler.cpp @@ -0,0 +1,191 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/sign/iav_primula_sign_handler.hpp" +#include "score/crypto/src/daemon/common/algorithm_info.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/sign/sign_executor.hpp" + +#include "score/mw/log/logging.h" + +#include +#include +#include + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ + +using common::DaemonErrorCode; +using common::ResponseParameters; + +/// @brief Return the expected signature size for a PQC signature algorithm. +/// +/// @return Signature size in bytes, or zero if the algorithm is not a +/// supported signature algorithm. +std::size_t SignatureSizeForAlgorithm(const common::AlgorithmId& algorithm) +{ + const auto info = common::LookupPqcAlgorithm(algorithm); + if (info.has_value() && (info->kind == common::PqcAlgorithmKind::kSignature)) + { + return info->signature_or_ciphertext_size; + } + return 0U; +} + +IavPrimulaSignHandler::IavPrimulaSignHandler(std::unique_ptr executor, + common::AlgorithmId algorithm) + : ScoreSignHandler{std::move(executor), std::move(algorithm)} +{ +} + +Expected IavPrimulaSignHandler::ValidateAlgorithm() const +{ + if (SignatureSizeForAlgorithm(m_algorithm) == 0U) + { + return make_unexpected(DaemonErrorCode::kUnsupportedAlgorithm); + } + return std::monostate{}; +} + +std::size_t IavPrimulaSignHandler::GetExpectedSignatureSize() const noexcept +{ + return SignatureSizeForAlgorithm(m_algorithm); +} + +Expected IavPrimulaSignHandler::InitializeContext( + const ::score::crypto::daemon::provider::handler::InitializationParams& init_params) +{ + score::mw::log::LogDebug() << "DEBUG: IavPrimulaSignHandler::InitializeContext called with algorithm:" + << m_algorithm; + + // Validate the algorithm and bind the non-owning native key handle required + // for signing. + const auto algorithm_result = ValidateAlgorithm(); + if (!algorithm_result.has_value()) + { + return make_unexpected(algorithm_result.error()); + } + + const auto base_result = ScoreSignHandler::InitializeContext(init_params); + if (!base_result.has_value()) + { + score::mw::log::LogError() << "ERROR: Base signature handler initialization failed in " + "IavPrimulaSignHandler::InitializeContext"; + return make_unexpected(base_result.error()); + } + + if (init_params.bound_key_handler == nullptr) + { + return make_unexpected(DaemonErrorCode::kKeySlotEmpty); + } + + const auto* primula_key = dynamic_cast(init_params.bound_key_handler); + if ((primula_key == nullptr) || (primula_key->GetNativeHandle() == nullptr)) + { + return make_unexpected(DaemonErrorCode::kIncompatibleKeyType); + } + + m_key = primula_key->GetNativeHandle(); + return std::monostate{}; +} + +Expected IavPrimulaSignHandler::Reset() +{ + // Clear the internally owned signature buffer before resetting the base + // handler state. + m_outputBuffer.clear(); + return ScoreSignHandler::Reset(); +} + +Expected IavPrimulaSignHandler::GetSignatureSize() const +{ + // Return the fixed signature size for the configured ML-DSA algorithm. + const auto size = SignatureSizeForAlgorithm(m_algorithm); + if (size == 0U) + { + return make_unexpected(DaemonErrorCode::kUnsupportedAlgorithm); + } + + ResponseParameters response; + response.emplace_back(static_cast(size)); + return response; +} + +Expected IavPrimulaSignHandler::SingleShotSign( + const common::RequestParameter& data, + std::optional output) +{ + const auto algorithm_result = ValidateAlgorithm(); + if (!algorithm_result.has_value()) + { + return make_unexpected(algorithm_result.error()); + } + + const auto* input = std::get_if>(&data); + if (input == nullptr) + { + return make_unexpected(DaemonErrorCode::kInvalidDataType); + } + + if (m_key == nullptr) + { + return make_unexpected(DaemonErrorCode::kKeySlotEmpty); + } + + // Sign the input in a single operation. Use an internally owned buffer + // when no output buffer is provided; otherwise write into the caller's buffer. + const auto expected_signature_length = GetExpectedSignatureSize(); + std::uint8_t* signature_data = nullptr; + const bool allocate_output_buffer = !output.has_value(); + + if (!allocate_output_buffer) + { + auto* output_buffer = std::get_if>(&output.value()); + if (output_buffer == nullptr) + { + return make_unexpected(DaemonErrorCode::kInvalidDataType); + } + if (output_buffer->data() == nullptr || output_buffer->size() < expected_signature_length) + { + return make_unexpected(DaemonErrorCode::kInsufficientBufferSize); + } + signature_data = output_buffer->data(); + } + else + { + m_outputBuffer.clear(); + m_outputBuffer.resize(expected_signature_length); + signature_data = m_outputBuffer.data(); + } + + std::size_t signature_length = expected_signature_length; + const auto status = iav_sign(m_key, input->data(), input->size(), signature_data, &signature_length); + if (status != IavStatusOk || signature_length != expected_signature_length) + { + return make_unexpected(DaemonErrorCode::kAlgorithmExecutionFailed); + } + + // Return owned output for internally allocated storage and a non-owning + // view for caller-provided storage. + ResponseParameters response; + if (allocate_output_buffer) + { + response.emplace_back(common::OwnedBuffer{std::move(m_outputBuffer)}); + } + else + { + response.emplace_back(score::cpp::span{signature_data, signature_length}); + } + return response; +} +} // namespace score::crypto::daemon::provider::score_provider::iav_primula diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/sign/iav_primula_sign_handler.hpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/sign/iav_primula_sign_handler.hpp new file mode 100644 index 000000000..0928e96cd --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/sign/iav_primula_sign_handler.hpp @@ -0,0 +1,79 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file iav_primula_sign_handler.hpp +/// @brief IAV-Primula implementation of the signature handler. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_SIGN_HANDLER_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_SIGN_HANDLER_HPP + +#include "score/crypto/src/daemon/provider/score_provider/operations/sign/score_sign_handler.hpp" +#include "score/iav_primula/include/iav_primula_ffi.h" + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ + +/// @brief IAV-Primula implementation of the provider-neutral signature handler. +/// +/// Supports ML-DSA signing through the IAV-Primula backend. The handler binds +/// a non-owning native key handle and manages the output buffer for +/// single-shot signatures. +class IavPrimulaSignHandler final : public operations::sign::ScoreSignHandler +{ + public: + /// @brief Create an IAV-Primula signature handler. + /// + /// Takes ownership of the operation executor and stores the selected ML-DSA + /// algorithm. + /// + /// @param executor Provider-neutral executor for signature operations. + /// @param algorithm ML-DSA algorithm identifier. + IavPrimulaSignHandler(std::unique_ptr executor, common::AlgorithmId algorithm); + + ~IavPrimulaSignHandler() override = default; + + IavPrimulaSignHandler(const IavPrimulaSignHandler&) = delete; + IavPrimulaSignHandler& operator=(const IavPrimulaSignHandler&) = delete; + IavPrimulaSignHandler(IavPrimulaSignHandler&&) = delete; + IavPrimulaSignHandler& operator=(IavPrimulaSignHandler&&) = delete; + + /// @brief Validate the algorithm and bind the signing key. + /// + /// The bound key must be an IAV-Primula key with a valid native handle. + [[nodiscard]] Expected InitializeContext( + const ::score::crypto::daemon::provider::handler::InitializationParams& init_params) override; + /// @brief Clear the internal output buffer and reset the handler state. + [[nodiscard]] Expected Reset() override; + /// @brief Sign a complete message in a single operation. + /// + /// If output is not provided, the handler allocates an owning response + /// buffer. Otherwise, the caller-provided output buffer is used. + [[nodiscard]] Expected SingleShotSign( + const common::RequestParameter& data, + std::optional output) override; + /// @brief Return the fixed signature size for the configured ML-DSA algorithm. + [[nodiscard]] Expected GetSignatureSize() const override; + + private: + /// @brief Validate that the configured algorithm is a supported ML-DSA algorithm. + [[nodiscard]] Expected ValidateAlgorithm() const; + /// @brief Return the expected signature size for the configured algorithm. + [[nodiscard]] std::size_t GetExpectedSignatureSize() const noexcept; + + iav_primula_key_handle* m_key{nullptr}; ///< Non-owning handle borrowed from the bound key handler. + std::vector m_outputBuffer; ///< Internally owned single-shot signature buffer. +}; + +} // namespace score::crypto::daemon::provider::score_provider::iav_primula + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_SIGN_HANDLER_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/verify/iav_primula_verify_handler.cpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/verify/iav_primula_verify_handler.cpp new file mode 100644 index 000000000..95af4aed5 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/verify/iav_primula_verify_handler.cpp @@ -0,0 +1,115 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/verify/iav_primula_verify_handler.hpp" + +#include "score/crypto/src/daemon/common/algorithm_info.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/verify/verify_executor.hpp" + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ +namespace +{ +/// @brief Return the expected signature size for a PQC signature algorithm. +/// +/// @return Signature size in bytes, or zero if the algorithm is not a +/// supported signature algorithm. +std::size_t SignatureSize(const common::AlgorithmId& algorithm) +{ + const auto info = common::LookupPqcAlgorithm(algorithm); + return info && info->kind == common::PqcAlgorithmKind::kSignature ? info->signature_or_ciphertext_size : 0U; +} +} // namespace + +IavPrimulaVerifyHandler::IavPrimulaVerifyHandler(std::unique_ptr executor, + common::AlgorithmId algorithm) + : ScoreVerifyHandler{std::move(executor), std::move(algorithm)} +{ +} + +Expected IavPrimulaVerifyHandler::ValidateAlgorithm() const +{ + if (SignatureSize(m_algorithm) == 0U) + { + return make_unexpected(common::DaemonErrorCode::kUnsupportedAlgorithm); + } + return std::monostate{}; +} + +Expected IavPrimulaVerifyHandler::InitializeContext( + const handler::InitializationParams& init_params) +{ + // Validate the algorithm and bind the non-owning native key handle required + // for signature verification. + auto algorithm = ValidateAlgorithm(); + if (!algorithm.has_value()) + { + return make_unexpected(algorithm.error()); + } + auto base = ScoreVerifyHandler::InitializeContext(init_params); + if (!base.has_value()) + { + return make_unexpected(base.error()); + } + if (init_params.bound_key_handler == nullptr) + { + return make_unexpected(common::DaemonErrorCode::kKeySlotEmpty); + } + const auto* key = dynamic_cast(init_params.bound_key_handler); + if (key == nullptr || key->GetNativeHandle() == nullptr) + { + return make_unexpected(common::DaemonErrorCode::kIncompatibleKeyType); + } + m_key = key->GetNativeHandle(); + return std::monostate{}; +} + +Expected IavPrimulaVerifyHandler::SingleShotVerify( + const common::RequestParameter& data, + const common::RequestParameter& signature) +{ + // Verify a complete message and signature in a single operation. + auto algorithm = ValidateAlgorithm(); + if (!algorithm.has_value()) + { + return make_unexpected(algorithm.error()); + } + const auto* message = std::get_if>(&data); + const auto* sig = std::get_if>(&signature); + if (message == nullptr || sig == nullptr) + { + return make_unexpected(common::DaemonErrorCode::kInvalidDataType); + } + if (m_key == nullptr) + { + return make_unexpected(common::DaemonErrorCode::kKeySlotEmpty); + } + if (sig->data() == nullptr || sig->size() != SignatureSize(m_algorithm)) + { + return make_unexpected(common::DaemonErrorCode::kInvalidArgument); + } + const auto status = iav_verify(m_key, message->data(), message->size(), sig->data(), sig->size()); + // Map backend verification status to the handler contract: an invalid + // signature returns false, while backend errors are returned as failures. + if (status == IavStatusVerificationFailed) + { + return false; + } + if (status != IavStatusOk) + { + return make_unexpected(common::DaemonErrorCode::kAlgorithmExecutionFailed); + } + return true; +} +} // namespace score::crypto::daemon::provider::score_provider::iav_primula diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/verify/iav_primula_verify_handler.hpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/verify/iav_primula_verify_handler.hpp new file mode 100644 index 000000000..e5090c002 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/operations/verify/iav_primula_verify_handler.hpp @@ -0,0 +1,76 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file iav_primula_verify_handler.hpp +/// @brief IAV-Primula implementation of the verification handler. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_VERIFY_HANDLER_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_VERIFY_HANDLER_HPP + +#include "score/crypto/src/daemon/provider/score_provider/operations/verify/score_verify_handler.hpp" +#include "score/iav_primula/include/iav_primula_ffi.h" + +namespace score::crypto::daemon::provider::score_provider::iav_primula +{ + +/// @brief IAV-Primula implementation of the provider-neutral verification handler. +/// +/// Supports ML-DSA signature verification through the IAV-Primula backend. +/// The handler binds a non-owning native key handle and performs single-shot +/// verification. +class IavPrimulaVerifyHandler final : public operations::verify::ScoreVerifyHandler +{ + public: + /// @brief Create an IAV-Primula verification handler. + /// + /// Takes ownership of the operation executor and stores the selected ML-DSA + /// algorithm. + /// + /// @param executor Provider-neutral executor for verification operations. + /// @param algorithm ML-DSA algorithm identifier. + IavPrimulaVerifyHandler(std::unique_ptr executor, + common::AlgorithmId algorithm); + ~IavPrimulaVerifyHandler() override = default; + + IavPrimulaVerifyHandler(const IavPrimulaVerifyHandler&) = delete; + IavPrimulaVerifyHandler& operator=(const IavPrimulaVerifyHandler&) = delete; + IavPrimulaVerifyHandler(const IavPrimulaVerifyHandler&&) = delete; + IavPrimulaVerifyHandler& operator=(const IavPrimulaVerifyHandler&&) = delete; + + /// @brief Validate the algorithm and bind the verification key. + /// + /// The bound key must be an IAV-Primula key with a valid native handle. + /// + /// @param init_params Context initialization parameters containing the + /// bound verification key. + [[nodiscard]] Expected InitializeContext( + const handler::InitializationParams& init_params) override; + /// @brief Verify a complete message and signature in a single operation. + /// + /// Returns true for a valid signature, false for an invalid signature, and + /// an error for invalid input, missing keys, or backend failures. + /// + /// @param data Message to verify. + /// @param signature Signature to verify against the message. + [[nodiscard]] Expected SingleShotVerify( + const common::RequestParameter& data, + const common::RequestParameter& signature) override; + + private: + /// @brief Validate that the configured algorithm is a supported ML-DSA algorithm. + [[nodiscard]] Expected ValidateAlgorithm() const; + iav_primula_key_handle* m_key{nullptr}; ///< Non-owning handle borrowed from the bound key handler. +}; +} // namespace score::crypto::daemon::provider::score_provider::iav_primula + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_IAV_PRIMULA_VERIFY_HANDLER_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/BUILD b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/BUILD new file mode 100644 index 000000000..921cf6baa --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/BUILD @@ -0,0 +1,41 @@ +load("@rules_cc//cc:defs.bzl", "cc_test") + +cc_test( + name = "iav_primula_key_management_test", + srcs = ["iav_primula_key_management_test.cpp"], + deps = [ + "//score/crypto/src/daemon/provider/score_provider:provider_iav_primula_library", + "@googletest//:gtest_main", + ], +) + +cc_test( + name = "iav_primula_signature_test", + srcs = ["iav_primula_signature_test.cpp"], + deps = [ + "//score/crypto/src/daemon/provider/score_provider:provider_iav_primula_library", + "//score/crypto/src/daemon/provider/score_provider/operations/sign:score_sign_handler", + "@googletest//:gtest_main", + ], +) + +cc_test( + name = "iav_primula_verification_test", + srcs = ["iav_primula_verification_test.cpp"], + deps = [ + "//score/crypto/src/daemon/provider/score_provider:provider_iav_primula_library", + "//score/crypto/src/daemon/provider/score_provider/operations/verify:score_verify_handler", + "@googletest//:gtest_main", + ], +) + +cc_test( + name = "iav_primula_kem_test", + srcs = ["iav_primula_kem_test.cpp"], + deps = [ + "//score/crypto/src/daemon/provider/handler:kem_handler_operations", + "//score/crypto/src/daemon/provider/score_provider:provider_iav_primula_library", + "//score/crypto/src/daemon/provider/score_provider/operations/kem:score_kem_handler", + "@googletest//:gtest_main", + ], +) diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_kem_test.cpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_kem_test.cpp new file mode 100644 index 000000000..f996ec813 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_kem_test.cpp @@ -0,0 +1,126 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/handler/handler_init_params.hpp" +#include "score/crypto/src/daemon/provider/handler/operations/kem_handler_operations.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/kem/iav_primula_kem_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/kem/kem_executor.hpp" + +#include + +#include + +namespace +{ +using namespace score::crypto::daemon; +using namespace score::crypto::daemon::provider::score_provider::iav_primula; +using Executor = score::crypto::daemon::provider::score_provider::operations::kem::KemExecutor; + +// --------------------------------------------------------------------------- +// Algorithm and input validation +// --------------------------------------------------------------------------- + +TEST(IavPrimulaKemTest, RejectsUnsupportedAlgorithm) +{ + IavPrimulaKemHandler handler{std::make_unique(), "ML-KEM-999"}; + auto result = handler.GenerateKeyPair(); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), common::DaemonErrorCode::kUnsupportedAlgorithm); +} + +TEST(IavPrimulaKemTest, PropagatesBackendStatusForKeyGeneration) +{ + IavPrimulaKemHandler handler{std::make_unique(), "ML-KEM-768"}; + auto result = handler.GenerateKeyPair(); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), common::DaemonErrorCode::kOperationFailed); +} + +TEST(IavPrimulaKemTest, RejectsInvalidEncapsulationInput) +{ + IavPrimulaKemHandler handler{std::make_unique(), "ML-KEM-768"}; + const std::uint8_t public_key[] = {1U, 2U}; + auto result = handler.Encapsulate(score::cpp::span{public_key, sizeof(public_key)}); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), common::DaemonErrorCode::kInvalidArgument); +} + +TEST(IavPrimulaKemTest, RequiresBoundKeyForDecapsulation) +{ + IavPrimulaKemHandler handler{std::make_unique(), "ML-KEM-768"}; + const std::uint8_t ciphertext[] = {1U, 2U}; + auto result = handler.Decapsulate(score::cpp::span{ciphertext, sizeof(ciphertext)}); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), common::DaemonErrorCode::kInvalidArgument); +} + +// --------------------------------------------------------------------------- +// Backend status propagation +// --------------------------------------------------------------------------- + +TEST(IavPrimulaKemTest, PropagatesBackendStatusForValidEncapsulation) +{ + IavPrimulaKemHandler handler{std::make_unique(), "ML-KEM-768"}; + // ML-KEM-768 public keys contain 1184 bytes. + const std::vector public_key(1184U, 0U); + auto result = handler.Encapsulate(score::cpp::span{public_key.data(), public_key.size()}); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), common::DaemonErrorCode::kOperationFailed); +} + +TEST(IavPrimulaKemTest, PropagatesBackendStatusForValidDecapsulation) +{ + IavPrimulaKemHandler handler{std::make_unique(), "ML-KEM-768"}; + // Use a non-null sentinel to simulate a bound native key handle. The + // backend operation is expected to fail before dereferencing this handle. + IavPrimulaKeyHandler key{reinterpret_cast(0x1), {}, {}}; + ::score::crypto::daemon::provider::handler::InitializationParams params{}; + params.bound_key_handler = &key; + ASSERT_TRUE(handler.InitializeContext(params).has_value()); + // ML-KEM-768 ciphertexts contain 1088 bytes. + const std::vector ciphertext(1088U, 0U); + auto result = handler.Decapsulate(score::cpp::span{ciphertext.data(), ciphertext.size()}); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), common::DaemonErrorCode::kOperationFailed); +} + +// --------------------------------------------------------------------------- +// Handler dispatch and context management +// --------------------------------------------------------------------------- + +TEST(IavPrimulaKemTest, DispatchesOperationsAndReset) +{ + // Verify that the handler dispatches both a KEM operation and RESET. + using namespace score::crypto::daemon::provider::handler::kem_handler_operations; + IavPrimulaKemHandler handler{std::make_unique(), "ML-KEM-768"}; + common::OperationIdentifier keygen{0U, KEM_KEYGEN}; + common::RequestParameters no_parameters{}; + auto keygen_result = handler.Execute(keygen, no_parameters); + ASSERT_FALSE(keygen_result.has_value()); + EXPECT_EQ(keygen_result.error(), common::DaemonErrorCode::kOperationFailed); + common::OperationIdentifier reset{0U, KEM_RESET}; + auto reset_result = handler.Execute(reset, no_parameters); + ASSERT_TRUE(reset_result.has_value()); + EXPECT_TRUE(reset_result->empty()); +} + +TEST(IavPrimulaKemTest, AllowsContextWithoutBoundKey) +{ + IavPrimulaKemHandler handler{std::make_unique(), "ML-KEM-768"}; + ::score::crypto::daemon::provider::handler::InitializationParams params{}; + // Context initialization is allowed without a bound key; decapsulation + // validates that a key is available when the operation is executed. + EXPECT_TRUE(handler.InitializeContext(params).has_value()); +} +} // namespace diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_key_management_test.cpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_key_management_test.cpp new file mode 100644 index 000000000..61b4c9bdd --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_key_management_test.cpp @@ -0,0 +1,96 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_factory.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp" + +#include + +namespace +{ +using namespace score::crypto::daemon; +using namespace score::crypto::daemon::provider::score_provider::iav_primula; + +// --------------------------------------------------------------------------- +// Import validation +// --------------------------------------------------------------------------- + +TEST(IavPrimulaKeyManagementTest, RejectsInvalidAlgorithmsAndKeys) +{ + IavPrimulaKeyFactory factory{common::ProviderId{7U}}; + key_management::KeyImportRequest request{}; + + // KEM public-key import validates the same public-key size as ML-DSA. + request.algorithm = "ML-KEM-768"; + std::vector kem_key(1184U); + request.key_data = kem_key.data(); + request.key_data_size = kem_key.size() - 1U; + auto unsupported_result = factory.ImportKey(request); + ASSERT_FALSE(unsupported_result.has_value()); + EXPECT_EQ(unsupported_result.error(), common::DaemonErrorCode::kInvalidArgument); + + // ML-DSA-44 public keys contain 1312 bytes; import one byte less + // deliberately to verify key-size validation. + request.algorithm = "ML-DSA-44"; + std::vector key(1312U); + request.key_data = key.data(); + request.key_data_size = key.size() - 1U; + auto invalid_result = factory.ImportKey(request); + ASSERT_FALSE(invalid_result.has_value()); + EXPECT_EQ(invalid_result.error(), common::DaemonErrorCode::kInvalidArgument); +} + +// --------------------------------------------------------------------------- +// Public-key ownership and lifecycle +// --------------------------------------------------------------------------- + +TEST(IavPrimulaKeyManagementTest, CopiesExportsAndReleasesPublicKey) +{ + key_management::ProviderKeyHandle handle{}; + handle.permissions = score::crypto::KeyOperationPermission::kExport; + // Use synthetic public-key material to verify that the handler copies it. + std::vector public_key(8U, 0xA5U); + IavPrimulaKeyHandler key{nullptr, public_key, handle}; + public_key[0] = 0U; + + // Export must return the copied key data, not the modified source vector. + auto exported = key.Export(); + ASSERT_TRUE(exported.has_value()); + EXPECT_EQ(exported->bytes, std::vector(8U, 0xA5U)); + + // Releasing the key prevents subsequent export operations. + EXPECT_TRUE(key.Release().has_value()); + auto released_export = key.Export(); + ASSERT_FALSE(released_export.has_value()); + EXPECT_EQ(released_export.error(), common::DaemonErrorCode::kKeyOperationNotPermitted); +} + +// --------------------------------------------------------------------------- +// Key-generation dispatch +// --------------------------------------------------------------------------- + +TEST(IavPrimulaKeyManagementTest, RoutesKemKeyGenerationToKemBackendPath) +{ + IavPrimulaKeyFactory factory{common::ProviderId{7U}}; + key_management::KeyGenerationRequest request{}; + request.algorithm = "ML-KEM-768"; + + // The current Rust FFI is a deliberate placeholder and therefore returns + // an operation failure. The call still exercises the KEM-specific branch + // in the factory; once the FFI is implemented this test should be changed + // to assert the generated key metadata and public-key size. + auto result = factory.GenerateKey(request); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), common::DaemonErrorCode::kOperationFailed); +} +} // namespace diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_signature_test.cpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_signature_test.cpp new file mode 100644 index 000000000..a56a91486 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_signature_test.cpp @@ -0,0 +1,75 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/handler/handler_init_params.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/sign/iav_primula_sign_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/sign/sign_executor.hpp" + +#include + +namespace +{ +using namespace score::crypto::daemon; +using namespace score::crypto::daemon::provider::score_provider::iav_primula; +using Executor = score::crypto::daemon::provider::score_provider::operations::sign::SignExecutor; + +// --------------------------------------------------------------------------- +// Signature algorithm sizes +// --------------------------------------------------------------------------- + +TEST(IavPrimulaSignatureTest, ReportsSupportedSizesAndRejectsKem) +{ + // Expected signature sizes for the supported ML-DSA variants. + const std::pair cases[] = { + // ML-DSA-44: 2420 bytes, ML-DSA-65: 3309 bytes, ML-DSA-87: 4627 bytes. + {"ML-DSA-44", 2420U}, + {"ML-DSA-65", 3309U}, + {"ML-DSA-87", 4627U}}; + for (const auto& test_case : cases) + { + IavPrimulaSignHandler handler{std::make_unique(), test_case.first}; + auto result = handler.GetSignatureSize(); + ASSERT_TRUE(result.has_value()); + EXPECT_EQ(std::get(result->front()), test_case.second); + } + + // A KEM algorithm is not a supported signature algorithm. + IavPrimulaSignHandler unsupported_handler{std::make_unique(), "ML-KEM-768"}; + auto result = unsupported_handler.GetSignatureSize(); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), common::DaemonErrorCode::kUnsupportedAlgorithm); +} + +// --------------------------------------------------------------------------- +// Output buffer validation +// --------------------------------------------------------------------------- + +TEST(IavPrimulaSignatureTest, ValidatesOutputBuffer) +{ + IavPrimulaSignHandler handler{std::make_unique(), "ML-DSA-44"}; + // Use a non-null sentinel to simulate a bound native key handle without + // creating a real backend key. + IavPrimulaKeyHandler key{reinterpret_cast(0x1), {}, {}}; + ::score::crypto::daemon::provider::handler::InitializationParams params{}; + params.bound_key_handler = &key; + ASSERT_TRUE(handler.InitializeContext(params).has_value()); + + const std::uint8_t message[] = {1U, 2U}; + // ML-DSA-44 signatures require 2420 bytes; ten bytes are intentionally too small. + std::vector output(10U); + common::RequestParameter input = score::cpp::span{message, 2U}; + auto result = handler.SingleShotSign(input, score::cpp::span{output.data(), output.size()}); + EXPECT_EQ(result.error(), common::DaemonErrorCode::kInsufficientBufferSize); +} +} // namespace diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_verification_test.cpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_verification_test.cpp new file mode 100644 index 000000000..40f091727 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/iav_primula_verification_test.cpp @@ -0,0 +1,96 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/handler/handler_init_params.hpp" +#include "score/crypto/src/daemon/provider/handler/operations/verify_handler_operations.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/verify/iav_primula_verify_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/verify/verify_executor.hpp" + +#include + +namespace +{ +using namespace score::crypto::daemon; +using namespace score::crypto::daemon::provider::score_provider::iav_primula; +using Executor = score::crypto::daemon::provider::score_provider::operations::verify::VerifyExecutor; + +// --------------------------------------------------------------------------- +// Algorithm and key validation +// --------------------------------------------------------------------------- + +TEST(IavPrimulaVerificationTest, RejectsUnsupportedAndMissingKeys) +{ + // ML-KEM-768 is not a supported signature-verification algorithm. + IavPrimulaVerifyHandler unsupported_handler{std::make_unique(), "ML-KEM-768"}; + auto unsupported_result = unsupported_handler.InitializeContext({}); + ASSERT_FALSE(unsupported_result.has_value()); + EXPECT_EQ(unsupported_result.error(), common::DaemonErrorCode::kUnsupportedAlgorithm); + + // ML-DSA-44 requires a bound verification key during initialization. + IavPrimulaVerifyHandler handler{std::make_unique(), "ML-DSA-44"}; + auto result = handler.InitializeContext({}); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), common::DaemonErrorCode::kKeySlotEmpty); +} + +// --------------------------------------------------------------------------- +// Signature input validation +// --------------------------------------------------------------------------- + +TEST(IavPrimulaVerificationTest, ValidatesKeyTypeAndSignatureSize) +{ + IavPrimulaVerifyHandler handler{std::make_unique(), "ML-DSA-44"}; + // A public-only key has no native handle and cannot be used for this + // verification operation. + IavPrimulaKeyHandler public_key{nullptr, std::vector(1312U), {}}; + ::score::crypto::daemon::provider::handler::InitializationParams params{}; + params.bound_key_handler = &public_key; + auto result = handler.InitializeContext(params); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), common::DaemonErrorCode::kIncompatibleKeyType); + + // Use a non-null sentinel to simulate a bound native key handle. + IavPrimulaKeyHandler key{reinterpret_cast(0x1), {}, {}}; + params.bound_key_handler = &key; + ASSERT_TRUE(handler.InitializeContext(params).has_value()); + const std::uint8_t message[] = {1U, 2U}; + // ML-DSA-44 signatures are 2420 bytes; ten bytes are intentionally invalid. + std::vector signature(10U); + common::RequestParameter input = score::cpp::span{message, 2U}; + auto verify = + handler.SingleShotVerify(input, score::cpp::span{signature.data(), signature.size()}); + EXPECT_EQ(verify.error(), common::DaemonErrorCode::kInvalidArgument); +} + +TEST(IavPrimulaVerificationTest, RejectsSingleShotRequestWithoutSignature) +{ + IavPrimulaVerifyHandler handler{std::make_unique(), "ML-DSA-44"}; + IavPrimulaKeyHandler key{reinterpret_cast(0x1), {}, {}}; + ::score::crypto::daemon::provider::handler::InitializationParams params{}; + params.bound_key_handler = &key; + ASSERT_TRUE(handler.InitializeContext(params).has_value()); + + const std::uint8_t message[] = {1U, 2U}; + common::RequestParameters request{ + score::cpp::span{message, 2U}, + }; + common::OperationIdentifier operation{}; + operation.operationAction = + ::score::crypto::daemon::provider::handler::verify_handler_operations::VERIFY_SS; + + auto result = handler.Execute(operation, request); + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error(), common::DaemonErrorCode::kInsufficientParameters); +} +} // namespace diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/integration_tests/BUILD b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/integration_tests/BUILD new file mode 100644 index 000000000..fd4b8782a --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/integration_tests/BUILD @@ -0,0 +1,14 @@ +load("@rules_cc//cc:defs.bzl", "cc_test") + +cc_test( + name = "iav_primula_application_integration_test", + srcs = ["iav_primula_application_integration_test.cpp"], + deps = [ + "//score/crypto/src/daemon/provider/handler:handler_headers", + "//score/crypto/src/daemon/provider/handler:sign_handler_operations", + "//score/crypto/src/daemon/provider/handler:verify_handler_operations", + "//score/crypto/src/daemon/provider/score_provider:provider_iav_primula_library", + "//score/crypto/src/daemon/provider/score_provider/operations/factory:score_handler_factory", + "@googletest//:gtest_main", + ], +) diff --git a/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/integration_tests/iav_primula_application_integration_test.cpp b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/integration_tests/iav_primula_application_integration_test.cpp new file mode 100644 index 000000000..008b6f7b7 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/iav_primula/tests/integration_tests/iav_primula_application_integration_test.cpp @@ -0,0 +1,103 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/handler/handler_init_params.hpp" +#include "score/crypto/src/daemon/provider/handler/operations/sign_handler_operations.hpp" +#include "score/crypto/src/daemon/provider/handler/operations/verify_handler_operations.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/iav_primula_provider.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/key_management/iav_primula_key_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/sign/iav_primula_sign_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/iav_primula/operations/verify/iav_primula_verify_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/factory/score_handler_factory.hpp" + +#include + +namespace +{ +using namespace score::crypto::daemon; +using namespace score::crypto::daemon::provider; +using namespace score::crypto::daemon::provider::score_provider; +using namespace score::crypto::daemon::provider::score_provider::iav_primula; + +// --------------------------------------------------------------------------- +// SIGN handler creation and initialization +// --------------------------------------------------------------------------- + +TEST(IavPrimulaApplicationIntegrationTest, CreatesSignHandlerFromProviderToAlgorithm) +{ + // Initialize the provider with the test provider ID and provider name. + IavPrimulaProvider provider; + ASSERT_TRUE(provider.Initialize(ProviderInitContext{common::ProviderId{7U}, "iavPrimula"})); + + // Create the provider-neutral factory and request an ML-DSA SIGN handler. + auto factory = provider.GetCryptoHandlerFactory(); + ASSERT_NE(factory, nullptr); + auto created = factory->CreateHandler("SIGN", "ML-DSA-44"); + ASSERT_TRUE(created.has_value()); + auto handler = created.value(); + ASSERT_NE(handler, nullptr); + auto* primula_handler = dynamic_cast(handler.get()); + ASSERT_NE(primula_handler, nullptr); + EXPECT_EQ(primula_handler->GetAlgorithm(), "ML-DSA-44"); + + // Use a non-null sentinel to simulate a bound native key handle without + // creating a real backend key. + IavPrimulaKeyHandler key{reinterpret_cast(0x1), {}, {}}; + handler::InitializationParams params{}; + params.bound_key_handler = &key; + ASSERT_TRUE(handler->InitializeContext(params).has_value()); + EXPECT_EQ(primula_handler->GetOperationState(), common::StreamOperationState::IDLE); + + // Initialization without a bound key must be rejected. + auto missing_key_initialization = handler->InitializeContext({}); + ASSERT_FALSE(missing_key_initialization.has_value()); + EXPECT_EQ(missing_key_initialization.error(), common::DaemonErrorCode::kKeySlotEmpty); + provider.Shutdown(); +} + +// --------------------------------------------------------------------------- +// VERIFY handler creation and initialization +// --------------------------------------------------------------------------- + +TEST(IavPrimulaApplicationIntegrationTest, CreatesVerifyHandlerAndReachesAlgorithmValidation) +{ + // Initialize the provider before obtaining its handler factory. + IavPrimulaProvider provider; + ASSERT_TRUE(provider.Initialize(ProviderInitContext{common::ProviderId{7U}, "iavPrimula"})); + + // Create a VERIFY handler for the ML-DSA-44 algorithm. + auto created = provider.GetCryptoHandlerFactory()->CreateHandler("VERIFY", "ML-DSA-44"); + ASSERT_TRUE(created.has_value()); + auto handler = created.value(); + ASSERT_NE(handler, nullptr); + auto* primula_handler = dynamic_cast(handler.get()); + ASSERT_NE(primula_handler, nullptr); + EXPECT_EQ(primula_handler->GetAlgorithm(), "ML-DSA-44"); + + // A non-null sentinel represents a bound native key handle for initialization. + IavPrimulaKeyHandler key{reinterpret_cast(0x1), {}, {}}; + handler::InitializationParams params{}; + params.bound_key_handler = &key; + ASSERT_TRUE(handler->InitializeContext(params).has_value()); + EXPECT_EQ(primula_handler->GetOperationState(), common::StreamOperationState::IDLE); + + // Public-only key material has no native handle and is incompatible with + // the native-key-based verification implementation. + IavPrimulaKeyHandler public_only_key{nullptr, std::vector(1312U), {}}; + params.bound_key_handler = &public_only_key; + auto incompatible_key_initialization = handler->InitializeContext(params); + ASSERT_FALSE(incompatible_key_initialization.has_value()); + EXPECT_EQ(incompatible_key_initialization.error(), common::DaemonErrorCode::kIncompatibleKeyType); + provider.Shutdown(); +} +} // namespace diff --git a/score/crypto/src/daemon/provider/score_provider/operations/factory/score_handler_factory.hpp b/score/crypto/src/daemon/provider/score_provider/operations/factory/score_handler_factory.hpp index 9a71c64d8..a34123b4a 100644 --- a/score/crypto/src/daemon/provider/score_provider/operations/factory/score_handler_factory.hpp +++ b/score/crypto/src/daemon/provider/score_provider/operations/factory/score_handler_factory.hpp @@ -44,22 +44,47 @@ class ScoreHandlerFactory : public handler::ICryptoHandlerFactory ~ScoreHandlerFactory() override = default; - /// Routes to CreateHashHandler, CreateMacHandler, or CreateKeyManagementHandler. + /// @brief Create a handler for the requested operation family. + /// + /// Dispatches to the provider-specific factory method selected by + /// handlerId. Unsupported handler identifiers result in an + /// unsupported-operation error. + /// + /// @param handlerId Operation family to create. + /// @param algorithm Algorithm identifier used by algorithm-specific handlers. ::score::Result CreateHandler(const common::HandlerId& handlerId, const common::AlgorithmId& algorithm) override; protected: - /// Override in concrete provider to create a hash handler. Default returns unsupported. + /// Override in a concrete provider to create a hash handler. + /// The default implementation returns kUnsupportedOperation. [[nodiscard]] virtual ::score::Result CreateHashHandler( const common::AlgorithmId& algorithm); - /// Override in concrete provider to create a MAC handler. Default returns unsupported. + /// Override in a concrete provider to create a MAC handler. + /// The default implementation returns kUnsupportedOperation. [[nodiscard]] virtual ::score::Result CreateMacHandler( const common::AlgorithmId& algorithm); - /// Override in concrete provider to create a key management handler. Default returns unsupported. + /// Override in a concrete provider to create a key management handler. + /// The default implementation returns kUnsupportedOperation. [[nodiscard]] virtual ::score::Result CreateKeyManagementHandler(); + /// Override in a concrete provider to create a signature handler. + /// The default implementation returns kUnsupportedOperation. + [[nodiscard]] virtual ::score::Result CreateSignHandler( + const common::AlgorithmId& algorithm); + + /// Override in a concrete provider to create a signature verification handler. + /// The default implementation returns kUnsupportedOperation. + [[nodiscard]] virtual ::score::Result CreateVerifyHandler( + const common::AlgorithmId& algorithm); + + /// Override in a concrete provider to create a key encapsulation handler. + /// The default implementation returns kUnsupportedOperation. + [[nodiscard]] virtual ::score::Result CreateKemHandler( + const common::AlgorithmId& algorithm); + std::shared_ptr m_key_factory; std::shared_ptr m_slot_handler; key_management::KeyManagementService::Sptr m_km_service; @@ -68,6 +93,9 @@ class ScoreHandlerFactory : public handler::ICryptoHandlerFactory static constexpr const char* HASH = "HASH"; static constexpr const char* MAC = "MAC"; static constexpr const char* KEY_MANAGEMENT = "KEY_MANAGEMENT"; + static constexpr const char* SIGN = "SIGN"; + static constexpr const char* VERIFY = "VERIFY"; + static constexpr const char* KEM = "KEM"; }; } // namespace score::crypto::daemon::provider::score_provider::operations::factory diff --git a/score/crypto/src/daemon/provider/score_provider/operations/factory/src/score_handler_factory.cpp b/score/crypto/src/daemon/provider/score_provider/operations/factory/src/score_handler_factory.cpp index d9c05aca7..ac593bda7 100644 --- a/score/crypto/src/daemon/provider/score_provider/operations/factory/src/score_handler_factory.cpp +++ b/score/crypto/src/daemon/provider/score_provider/operations/factory/src/score_handler_factory.cpp @@ -42,6 +42,18 @@ ::score::Result ScoreHandlerFactory::CreateHandler(const { return CreateKeyManagementHandler(); } + if (handlerId == SIGN) + { + return CreateSignHandler(algorithm); + } + if (handlerId == VERIFY) + { + return CreateVerifyHandler(algorithm); + } + if (handlerId == KEM) + { + return CreateKemHandler(algorithm); + } ::score::result::Error error( static_cast<::score::result::ErrorCode>(::score::crypto::CryptoErrorCode::kUnsupportedOperation), @@ -51,7 +63,7 @@ ::score::Result ScoreHandlerFactory::CreateHandler(const } // --------------------------------------------------------------------------- -// Default implementations — return unsupported +// Default provider hooks — return kUnsupportedOperation when not overridden. // --------------------------------------------------------------------------- ::score::Result ScoreHandlerFactory::CreateHashHandler(const common::AlgorithmId& /*algorithm*/) @@ -81,4 +93,32 @@ ::score::Result ScoreHandlerFactory::CreateKeyManagement return ::score::Result(::score::unexpect, error); } +::score::Result ScoreHandlerFactory::CreateSignHandler(const common::AlgorithmId& /*algorithm*/) +{ + ::score::result::Error error( + static_cast<::score::result::ErrorCode>(::score::crypto::CryptoErrorCode::kUnsupportedOperation), + ::score::crypto::kCryptoErrorDomain, + "Signature handler not supported by this score provider"); + return ::score::Result(::score::unexpect, error); +} + +::score::Result ScoreHandlerFactory::CreateVerifyHandler( + const common::AlgorithmId& /*algorithm*/) +{ + ::score::result::Error error( + static_cast<::score::result::ErrorCode>(::score::crypto::CryptoErrorCode::kUnsupportedOperation), + ::score::crypto::kCryptoErrorDomain, + "Signature verification handler not supported by this score provider"); + return ::score::Result(::score::unexpect, error); +} + +::score::Result ScoreHandlerFactory::CreateKemHandler(const common::AlgorithmId& /*algorithm*/) +{ + ::score::result::Error error( + static_cast<::score::result::ErrorCode>(::score::crypto::CryptoErrorCode::kUnsupportedOperation), + ::score::crypto::kCryptoErrorDomain, + "Key encapsulation handler not supported by this score provider"); + return ::score::Result(::score::unexpect, error); +} + } // namespace score::crypto::daemon::provider::score_provider::operations::factory diff --git a/score/crypto/src/daemon/provider/score_provider/operations/kem/BUILD b/score/crypto/src/daemon/provider/score_provider/operations/kem/BUILD new file mode 100644 index 000000000..735e706c5 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/kem/BUILD @@ -0,0 +1,12 @@ +load("@rules_cc//cc:defs.bzl", "cc_library") +cc_library( + name = "score_kem_handler", + srcs = ["src/score_kem_handler.cpp", "src/kem_executor.cpp"], + hdrs = ["score_kem_handler.hpp", "kem_executor.hpp"], + visibility = ["//:__subpackages__"], + deps = [ + "//score/crypto/src/daemon/common", + "//score/crypto/src/daemon/provider/handler:handler_headers", + "//score/crypto/src/daemon/provider/handler:kem_handler_operations", + ], +) diff --git a/score/crypto/src/daemon/provider/score_provider/operations/kem/kem_executor.hpp b/score/crypto/src/daemon/provider/score_provider/operations/kem/kem_executor.hpp new file mode 100644 index 000000000..902d9f6e8 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/kem/kem_executor.hpp @@ -0,0 +1,53 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file kem_executor.hpp +/// @brief Operation dispatcher for provider-neutral KEM handlers. + +#ifndef SCORE_CRYPTO_DAEMON_SCORE_PROVIDER_KEM_EXECUTOR_HPP +#define SCORE_CRYPTO_DAEMON_SCORE_PROVIDER_KEM_EXECUTOR_HPP + +#include "score/crypto/src/common/types.hpp" +#include "score/crypto/src/daemon/common/daemon_error.hpp" +#include "score/crypto/src/daemon/common/types.hpp" + +namespace score::crypto::daemon::provider::score_provider::operations::kem +{ + +class ScoreKemHandler; + +/// @brief Stateless dispatcher for one-shot KEM operations. +/// +/// The executor validates operation parameter counts and dispatches key +/// generation, encapsulation, decapsulation, and reset operations to +/// ScoreKemHandler. +class KemExecutor final +{ + public: + /// @brief Execute one KEM operation. + /// + /// Dispatches the operation identified by the operation action to the + /// corresponding ScoreKemHandler method. + /// + /// @param handler KEM handler receiving the operation. + /// @param operation Operation identifier containing the KEM action. + /// @param request Operation parameters. + /// @return Operation response, or a daemon error if the parameters or + /// operation are invalid. + Expected Execute(ScoreKemHandler& handler, + const common::OperationIdentifier& operation, + common::RequestParameters& request); +}; +} // namespace score::crypto::daemon::provider::score_provider::operations::kem + +#endif // SCORE_CRYPTO_DAEMON_SCORE_PROVIDER_KEM_EXECUTOR_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/operations/kem/score_kem_handler.hpp b/score/crypto/src/daemon/provider/score_provider/operations/kem/score_kem_handler.hpp new file mode 100644 index 000000000..4266ae599 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/kem/score_kem_handler.hpp @@ -0,0 +1,86 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file score_kem_handler.hpp +/// @brief Provider-neutral base handler for KEM operations. + +#ifndef SCORE_CRYPTO_DAEMON_SCORE_PROVIDER_KEM_HANDLER_HPP +#define SCORE_CRYPTO_DAEMON_SCORE_PROVIDER_KEM_HANDLER_HPP + +#include "score/crypto/src/daemon/common/daemon_error.hpp" +#include "score/crypto/src/daemon/common/types.hpp" +#include "score/crypto/src/daemon/provider/handler/i_handler.hpp" +#include +#include + +namespace score::crypto::daemon::provider::score_provider::operations::kem +{ + +class KemExecutor; + +/// @brief Provider-neutral base handler for one-shot KEM operations. +/// +/// Delegates operation dispatch to the injected KemExecutor. Concrete +/// provider handlers override the typed KEM methods to implement key +/// generation, encapsulation, and decapsulation. +class ScoreKemHandler : public handler::Handler +{ + public: + /// @brief Create a provider-neutral KEM handler. + /// + /// @param executor Executor used to dispatch KEM operations. + /// @param algorithm Algorithm identifier handled by this instance. + ScoreKemHandler(std::unique_ptr, common::AlgorithmId); + ~ScoreKemHandler() override; + + ScoreKemHandler(const ScoreKemHandler&) = delete; + ScoreKemHandler& operator=(const ScoreKemHandler&) = delete; + ScoreKemHandler(ScoreKemHandler&&) = delete; + ScoreKemHandler& operator=(ScoreKemHandler&&) = delete; + + /// @brief Delegate one KEM operation to the injected executor. + Expected Execute(const common::OperationIdentifier&, + common::RequestParameters&) override; + + /// @brief Initialize the KEM operation context. + Expected InitializeContext(const handler::InitializationParams&) override; + + /// @brief Reset the KEM handler state. + Expected Reset() override; + + /// @brief Generate a KEM key pair. + /// + /// Concrete providers override this method to return the generated public + /// key or provider-specific key-generation output. + virtual Expected GenerateKeyPair(); + + /// @brief Encapsulate a shared secret using a public key. + /// + /// Concrete providers override this method to return the ciphertext and + /// shared secret. + virtual Expected Encapsulate(const common::RequestParameter&); + + /// @brief Decapsulate a ciphertext using the bound private key. + /// + /// Concrete providers override this method to return the shared secret. + virtual Expected Decapsulate(const common::RequestParameter&); + + protected: + common::AlgorithmId m_algorithm; ///< Algorithm handled by this instance. + + private: + std::unique_ptr m_executor; ///< Owns the operation dispatcher. +}; +} // namespace score::crypto::daemon::provider::score_provider::operations::kem + +#endif // SCORE_CRYPTO_DAEMON_SCORE_PROVIDER_KEM_HANDLER_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/operations/kem/src/kem_executor.cpp b/score/crypto/src/daemon/provider/score_provider/operations/kem/src/kem_executor.cpp new file mode 100644 index 000000000..5ed90980c --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/kem/src/kem_executor.cpp @@ -0,0 +1,72 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/operations/kem/kem_executor.hpp" +#include "score/crypto/src/daemon/provider/handler/operations/kem_handler_operations.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/kem/score_kem_handler.hpp" + +namespace score::crypto::daemon::provider::score_provider::operations::kem +{ + +namespace ops = ::score::crypto::daemon::provider::handler::kem_handler_operations; + +Expected KemExecutor::Execute( + ScoreKemHandler& handler, + const common::OperationIdentifier& operation, + common::RequestParameters& request) +{ + // Dispatch the KEM operation and enforce the parameter requirements for + // each operation type. + switch (operation.operationAction) + { + case ops::KEM_KEYGEN: + { + if (!request.empty()) + { + return make_unexpected(common::DaemonErrorCode::kInvalidArgument); + } + return handler.GenerateKeyPair(); + } + case ops::KEM_ENCAPSULATE: + { + if (request.empty()) + { + return make_unexpected(common::DaemonErrorCode::kInsufficientParameters); + } + return handler.Encapsulate(request[0]); + } + case ops::KEM_DECAPSULATE: + { + if (request.empty()) + { + return make_unexpected(common::DaemonErrorCode::kInsufficientParameters); + } + return handler.Decapsulate(request[0]); + } + case ops::KEM_RESET: + { + auto reset_result = handler.Reset(); + // Reset does not produce response data; propagate any handler error. + if (!reset_result.has_value()) + { + return make_unexpected(reset_result.error()); + } + return {}; + } + default: + { // Reject operation actions that are not part of the KEM operation namespace. + return make_unexpected(common::DaemonErrorCode::kInvalidOperation); + } + } +} +} // namespace score::crypto::daemon::provider::score_provider::operations::kem diff --git a/score/crypto/src/daemon/provider/score_provider/operations/kem/src/score_kem_handler.cpp b/score/crypto/src/daemon/provider/score_provider/operations/kem/src/score_kem_handler.cpp new file mode 100644 index 000000000..a95761945 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/kem/src/score_kem_handler.cpp @@ -0,0 +1,66 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/operations/kem/score_kem_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/kem/kem_executor.hpp" + +namespace score::crypto::daemon::provider::score_provider::operations::kem +{ + +ScoreKemHandler::ScoreKemHandler(std::unique_ptr executor, common::AlgorithmId algorithm) + : m_algorithm{std::move(algorithm)}, m_executor{std::move(executor)} +{ +} + +ScoreKemHandler::~ScoreKemHandler() = default; + +Expected ScoreKemHandler::Execute( + const common::OperationIdentifier& operation, + common::RequestParameters& request) +{ + // Delegate operation dispatch to the injected KEM executor. + return m_executor->Execute(*this, operation, request); +} + +Expected ScoreKemHandler::InitializeContext( + const handler::InitializationParams&) +{ + // The provider-neutral base handler has no context-specific state to initialize. + return {}; +} + +Expected ScoreKemHandler::Reset() +{ + // The provider-neutral base handler has no state to reset. + return {}; +} + +// --------------------------------------------------------------------------- +// Default typed operations — return unsupported unless overridden +// --------------------------------------------------------------------------- + +Expected ScoreKemHandler::GenerateKeyPair() +{ + return make_unexpected(common::DaemonErrorCode::kUnsupportedOperation); +} +Expected ScoreKemHandler::Encapsulate( + const common::RequestParameter&) +{ + return make_unexpected(common::DaemonErrorCode::kUnsupportedOperation); +} +Expected ScoreKemHandler::Decapsulate( + const common::RequestParameter&) +{ + return make_unexpected(common::DaemonErrorCode::kUnsupportedOperation); +} +} // namespace score::crypto::daemon::provider::score_provider::operations::kem diff --git a/score/crypto/src/daemon/provider/score_provider/operations/sign/BUILD b/score/crypto/src/daemon/provider/score_provider/operations/sign/BUILD new file mode 100644 index 000000000..0944bfcb5 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/sign/BUILD @@ -0,0 +1,13 @@ +load("@rules_cc//cc:defs.bzl", "cc_library") +cc_library( + name = "score_sign_handler", + srcs = ["src/score_sign_handler.cpp", "src/sign_executor.cpp"], + hdrs = ["score_sign_handler.hpp", "sign_executor.hpp"], + visibility = ["//:__subpackages__"], + deps = [ + "//score/crypto/src/daemon/common", + "//score/crypto/src/daemon/provider/handler:handler_headers", + "//score/crypto/src/daemon/provider/handler:handler_utils_impl", + "//score/crypto/src/daemon/provider/handler:sign_handler_operations", + ], +) diff --git a/score/crypto/src/daemon/provider/score_provider/operations/sign/score_sign_handler.hpp b/score/crypto/src/daemon/provider/score_provider/operations/sign/score_sign_handler.hpp new file mode 100644 index 000000000..61adbabc6 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/sign/score_sign_handler.hpp @@ -0,0 +1,143 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file score_sign_handler.hpp +/// @brief Provider-neutral base handler for signature operations. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_SCORE_PROVIDER_OPERATIONS_SIGN_SCORE_SIGN_HANDLER_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_SCORE_PROVIDER_OPERATIONS_SIGN_SCORE_SIGN_HANDLER_HPP + +#include "score/crypto/src/daemon/common/daemon_error.hpp" +#include "score/crypto/src/daemon/common/types.hpp" +#include "score/crypto/src/daemon/provider/handler/i_handler.hpp" +#include +#include +#include + +namespace score::crypto::daemon::provider::score_provider::operations::sign +{ + +/// @brief Forward declaration of the signature-operation executor (m_executor). +class SignExecutor; + +/// @brief Abstract base handler for signature operations under the score interface family. +/// +/// Implements the daemon's Handler interface by delegating Execute() to the +/// injected SignExecutor. Concrete score-interface providers (e.g. OpenSSL, IAV-Primula) +/// inherit from this class and override the typed signature methods. +/// +/// Typed methods default to kUnsupportedOperation so that a partially-implemented +/// provider compiles and returns a clear error at runtime. +/// +/// State management (algorithm, stream operation state) is centralised here. +class ScoreSignHandler : public handler::Handler +{ + public: + using Sptr = std::shared_ptr; + + ScoreSignHandler() = delete; + + /// @brief Create a provider-neutral signature handler. + /// + /// Takes ownership of the operation executor and stores the selected + /// signature algorithm. + /// + /// @param executor Executor used to dispatch signature operations. + /// @param algorithm Algorithm identifier handled by this instance. + ScoreSignHandler(std::unique_ptr executor, const common::AlgorithmId algorithm); + ~ScoreSignHandler() override; + + /// @brief Delegates to the injected executor. + /// + /// @param operation Operation identifier containing the signature action. + /// @param request Operation parameters. + [[nodiscard]] Expected Execute( + const common::OperationIdentifier& operation, + common::RequestParameters& request) override; + + /// @brief Initialize the handler context and reset the stream state to IDLE. + /// + /// @param init_params Context initialization parameters. + [[nodiscard]] Expected InitializeContext( + const handler::InitializationParams& init_params) override; + + /// @brief Reset the intermediate stream state back to IDLE. + [[nodiscard]] Expected Reset() override; + + // ----------------------------------------------------------------------- + // Stream state management + // ----------------------------------------------------------------------- + + /// @brief Return the current signature stream state. + [[nodiscard]] common::StreamOperationState GetOperationState() const noexcept + { + return m_state; + } + + /// @brief Set the current signature stream state. + void SetOperationState(common::StreamOperationState state) noexcept + { + m_state = state; + } + + /// @brief Return the configured signature algorithm. + [[nodiscard]] const common::AlgorithmId& GetAlgorithm() const noexcept + { + return m_algorithm; + } + + // ----------------------------------------------------------------------- + // Typed signature operations — override in concrete provider handlers + // ----------------------------------------------------------------------- + + /// @brief Initialize a signature operation on an existing context. + /// + /// @param initial_data Optional data to include during initialization. + [[nodiscard]] virtual Expected InitSign( + std::optional initial_data); + + /// @brief Add data to the active signature stream. + /// + /// @param data Message data to add to the signature. + [[nodiscard]] virtual Expected UpdateSign( + const common::RequestParameter& data); + + /// @brief Finalize the signature and produce the output. + /// + /// @param final_data Optional final data to add before signing. + /// @param output Optional caller-provided output buffer. + [[nodiscard]] virtual Expected FinalizeSign( + std::optional final_data, + std::optional output); + + /// @brief Perform a single-shot signature without streaming. + /// + /// @param data Message data to sign. + /// @param output Optional caller-provided output buffer. + [[nodiscard]] virtual Expected SingleShotSign( + const common::RequestParameter& data, + std::optional output); + + /// @brief Get the signature size for the current algorithm. + [[nodiscard]] virtual Expected GetSignatureSize() const; + + protected: + common::AlgorithmId m_algorithm; ///< Algorithm handled by this instance. + common::StreamOperationState m_state{common::StreamOperationState::IDLE}; ///< Current streaming state. + + private: + std::unique_ptr m_executor; ///< Owns the operation dispatcher. +}; +} // namespace score::crypto::daemon::provider::score_provider::operations::sign + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_SCORE_PROVIDER_OPERATIONS_SIGN_SCORE_SIGN_HANDLER_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/operations/sign/sign_executor.hpp b/score/crypto/src/daemon/provider/score_provider/operations/sign/sign_executor.hpp new file mode 100644 index 000000000..4b595187a --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/sign/sign_executor.hpp @@ -0,0 +1,120 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file sign_executor.hpp +/// @brief Operation dispatcher for provider-neutral signature handlers. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_SCORE_PROVIDER_OPERATIONS_SIGN_SIGN_EXECUTOR_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_SCORE_PROVIDER_OPERATIONS_SIGN_SIGN_EXECUTOR_HPP + +#include "score/crypto/src/common/types.hpp" +#include "score/crypto/src/daemon/common/daemon_error.hpp" +#include "score/crypto/src/daemon/common/types.hpp" + +namespace score::crypto::daemon::provider::score_provider::operations::sign +{ +/// @brief Forward declaration of the provider-neutral signature handler. +class ScoreSignHandler; + +/// @brief Stateless dispatcher for provider-neutral signature operations. +/// +/// Validates operation requests and streaming state transitions, then delegates +/// each operation to the corresponding ScoreSignHandler method. The executor +/// does not store operation state; the state is maintained by the handler. +class SignExecutor final +{ + public: + /// @brief Execute one SIGN operation. + /// + /// Dispatches the operation identified by the operation action to the + /// corresponding ScoreSignHandler method. + /// + /// @param handler Signature handler receiving the operation. + /// @param operation Operation identifier containing the signature action. + /// @param request Operation parameters. + /// @return Operation response, or a daemon error if the parameters, + /// operation, or stream state are invalid. + [[nodiscard]] Expected Execute( + ScoreSignHandler& handler, + const common::OperationIdentifier& operation, + common::RequestParameters& request); + + private: + /// @brief Execute the initialization step of a streaming signature. + /// + /// @param handler Signature handler receiving the operation. + /// @param request Optional initialization data. + /// @return Success, or a daemon error reported by the handler. + [[nodiscard]] Expected ExecuteInit(ScoreSignHandler& handler, + common::RequestParameters& request); + + /// @brief Add data to an active streaming signature. + /// + /// @param handler Signature handler receiving the operation. + /// @param request Request containing the data to be added. + /// @return Success, or a daemon error if the request is invalid or the + /// handler rejects the operation. + [[nodiscard]] Expected ExecuteUpdate(ScoreSignHandler& handler, + common::RequestParameters& request); + + /// @brief Finalize a streaming signature. + /// + /// @param handler Signature handler receiving the operation. + /// @param request Optional output buffer and final data. + /// @return Signature response, or a daemon error reported by the handler. + [[nodiscard]] Expected ExecuteFinalize( + ScoreSignHandler& handler, + common::RequestParameters& request); + + /// @brief Execute a single-shot signature operation. + /// + /// @param handler Signature handler receiving the operation. + /// @param request Input data and an optional output buffer. + /// @return Signature response, or a daemon error if the request is invalid + /// or the handler rejects the operation. + [[nodiscard]] Expected ExecuteSingleShot( + ScoreSignHandler& handler, + common::RequestParameters& request); + + /// @brief Reset the signature handler to its initial stream state. + /// + /// @param handler Signature handler receiving the reset operation. + /// @param request Reset operation parameters, which are unused. + /// @return Success, or a daemon error reported by the handler. + [[nodiscard]] Expected ExecuteReset(ScoreSignHandler& handler, + common::RequestParameters& request); + + /// @brief Query the signature size for the configured algorithm. + /// + /// @param handler Signature handler providing the algorithm-specific size. + /// @param request Operation parameters, which are unused. + /// @return Signature size response, or a daemon error reported by the handler. + [[nodiscard]] Expected GetSignatureSize( + const ScoreSignHandler& handler, + common::RequestParameters& request); + + /// @brief Validate a streaming operation and determine its next state. + /// + /// @param action Streaming operation to validate. + /// @param currentState Current signature stream state. + /// @param nextState Receives the state resulting from the operation. + /// @return Success with the next state, or a daemon error for an invalid + /// operation or state transition. + [[nodiscard]] static Expected ValidateStreamTransition( + common::OperationAction action, + common::StreamOperationState currentState, + common::StreamOperationState& nextState); +}; +} // namespace score::crypto::daemon::provider::score_provider::operations::sign + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_SCORE_PROVIDER_OPERATIONS_SIGN_SIGN_EXECUTOR_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/operations/sign/src/score_sign_handler.cpp b/score/crypto/src/daemon/provider/score_provider/operations/sign/src/score_sign_handler.cpp new file mode 100644 index 000000000..532414004 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/sign/src/score_sign_handler.cpp @@ -0,0 +1,85 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/operations/sign/score_sign_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/sign/sign_executor.hpp" + +namespace score::crypto::daemon::provider::score_provider::operations::sign +{ + +// The handler owns the executor and stores the algorithm used by the provider. +ScoreSignHandler::ScoreSignHandler(std::unique_ptr executor, const common::AlgorithmId algorithm) + : m_algorithm{std::move(algorithm)}, m_executor{std::move(executor)} +{ +} + +ScoreSignHandler::~ScoreSignHandler() = default; + +Expected ScoreSignHandler::Execute( + const common::OperationIdentifier& operation, + common::RequestParameters& request) +{ + // Delegate operation dispatch to the injected signature executor. + return m_executor->Execute(*this, operation, request); +} + +Expected ScoreSignHandler::InitializeContext( + const handler::InitializationParams& /*init_params*/) +{ + // Reset the streaming state when a new handler context is initialized. + m_state = common::StreamOperationState::IDLE; + return std::monostate{}; +} + +Expected ScoreSignHandler::Reset() +{ + // Reset the streaming state; provider-specific resources are reset by + // concrete handlers when they override this method. + m_state = common::StreamOperationState::IDLE; + return std::monostate{}; +} + +// --------------------------------------------------------------------------- +// Default typed operations — return unsupported unless overridden +// --------------------------------------------------------------------------- + +Expected ScoreSignHandler::InitSign( + std::optional /*initial_data*/) +{ + return make_unexpected(common::DaemonErrorCode::kUnsupportedOperation); +} + +Expected ScoreSignHandler::UpdateSign(const common::RequestParameter& /*data*/) +{ + return make_unexpected(common::DaemonErrorCode::kUnsupportedOperation); +} + +Expected ScoreSignHandler::FinalizeSign( + std::optional /*final_data*/, + std::optional /*output*/) +{ + return make_unexpected(common::DaemonErrorCode::kUnsupportedOperation); +} + +Expected ScoreSignHandler::SingleShotSign( + const common::RequestParameter& /*data*/, + std::optional /*output*/) +{ + return make_unexpected(common::DaemonErrorCode::kUnsupportedOperation); +} + +Expected ScoreSignHandler::GetSignatureSize() const +{ + return make_unexpected(common::DaemonErrorCode::kUnsupportedOperation); +} +} // namespace score::crypto::daemon::provider::score_provider::operations::sign diff --git a/score/crypto/src/daemon/provider/score_provider/operations/sign/src/sign_executor.cpp b/score/crypto/src/daemon/provider/score_provider/operations/sign/src/sign_executor.cpp new file mode 100644 index 000000000..d77919192 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/sign/src/sign_executor.cpp @@ -0,0 +1,247 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/operations/sign/sign_executor.hpp" +#include "score/crypto/src/daemon/provider/handler/operations/sign_handler_operations.hpp" +#include "score/crypto/src/daemon/provider/handler/src/handler_utils.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/sign/score_sign_handler.hpp" + +namespace score::crypto::daemon::provider::score_provider::operations::sign +{ +namespace handler = ::score::crypto::daemon::provider::handler; +using common::DaemonErrorCode; +using common::RequestParameters; +using common::ResponseParameters; +using common::StreamOperationState; + +Expected SignExecutor::Execute(ScoreSignHandler& handler, + const common::OperationIdentifier& operationId, + RequestParameters& request) +{ + // Handle operations that do not participate in the streaming state machine. + if (operationId.operationAction == handler::sign_handler_operations::SIGN_GET_SIGNATURE_SIZE) + { + return GetSignatureSize(handler, request); + } + + if (operationId.operationAction == handler::sign_handler_operations::SIGN_RESET) + { + auto result = ExecuteReset(handler, request); + if (!result.has_value()) + { + return make_unexpected(result.error()); + } + return ResponseParameters{}; + } + + // A single-shot signature is only valid while no streaming operation is active. + if (operationId.operationAction == handler::sign_handler_operations::SIGN_SS) + { + StreamOperationState state = handler.GetOperationState(); + if (state != StreamOperationState::IDLE) + { + return make_unexpected(DaemonErrorCode::kOperationInProgress); + } + if (request.empty()) + { + return make_unexpected(DaemonErrorCode::kInsufficientParameters); + } + + return ExecuteSingleShot(handler, request); + } + + // Streaming operations must follow the valid state-machine transition before + // the corresponding handler method is called. + StreamOperationState currentState = handler.GetOperationState(); + StreamOperationState nextState = StreamOperationState::IDLE; + const auto sequenceValidation = ValidateStreamTransition(operationId.operationAction, currentState, nextState); + if (!sequenceValidation.has_value()) + { + return make_unexpected(sequenceValidation.error()); + } + + // Finalization returns a response and updates the state only after success. + if (operationId.operationAction == handler::sign_handler_operations::SIGN_FINALIZE) + { + auto result = ExecuteFinalize(handler, request); + if (result.has_value()) + { + handler.SetOperationState(nextState); + } + return result; + } + + // Initialization and update return no response parameters. The stream state + // is advanced only when the handler accepts the operation. + if (operationId.operationAction == handler::sign_handler_operations::SIGN_INIT) + { + const auto result = ExecuteInit(handler, request); + if (result.has_value()) + { + handler.SetOperationState(nextState); + } + else + { + return make_unexpected(result.error()); + } + } + + if (operationId.operationAction == handler::sign_handler_operations::SIGN_UPDATE) + { + const auto result = ExecuteUpdate(handler, request); + if (result.has_value()) + { + handler.SetOperationState(nextState); + } + else + { + return make_unexpected(result.error()); + } + } + + return ResponseParameters{}; +} + +Expected SignExecutor::ExecuteInit(ScoreSignHandler& handler, + RequestParameters& request) +{ + // Initialization data is optional; a missing or incompatible first + // parameter is treated as no initial data and handled by the provider. + std::optional> initialData; + if (!request.empty()) + { + if (auto* buf = std::get_if>(&request[0])) + { + initialData.emplace(*buf); + } + } + return handler.InitSign(initialData); +} + +Expected SignExecutor::ExecuteUpdate(ScoreSignHandler& handler, + RequestParameters& request) +{ + // UPDATE requires one input buffer containing data for the active stream. + if (request.empty()) + { + return make_unexpected(DaemonErrorCode::kInsufficientParameters); + } + + auto* buf = std::get_if>(&request[0]); + if (buf == nullptr) + { + return make_unexpected(DaemonErrorCode::kInvalidDataType); + } + + return handler.UpdateSign(*buf); +} + +Expected SignExecutor::ExecuteFinalize(ScoreSignHandler& handler, + RequestParameters& request) +{ + // FINALIZE accepts an optional output buffer followed by optional final data. + std::optional> output; + if (!request.empty()) + { + if (auto* buf = std::get_if>(&request[0])) + { + output.emplace(*buf); + } + } + + std::optional> finalData; + if (request.size() > 1) + { + if (auto* buf = std::get_if>(&request[1])) + { + finalData.emplace(*buf); + } + } + + return handler.FinalizeSign(output, finalData); +} + +Expected SignExecutor::ExecuteSingleShot(ScoreSignHandler& handler, + RequestParameters& request) +{ + // SINGLE-SHOT requires input data and may optionally receive an output buffer. + if (request.empty()) + { + return make_unexpected(DaemonErrorCode::kInsufficientParameters); + } + + auto* data = std::get_if>(&request[0]); + if (data == nullptr) + { + return make_unexpected(DaemonErrorCode::kInvalidDataType); + } + + std::optional> output; + if (request.size() > 1) + { + if (auto* buf = std::get_if>(&request[1])) + { + output.emplace(*buf); + } + } + + return handler.SingleShotSign(*data, output); +} + +Expected SignExecutor::ExecuteReset(ScoreSignHandler& handler, + RequestParameters& /*request*/) +{ + // RESET does not consume request parameters; the handler owns the reset logic. + return handler.Reset(); +} + +Expected SignExecutor::GetSignatureSize(const ScoreSignHandler& handler, + RequestParameters& /*request*/) +{ + // The signature size depends only on the configured algorithm. + return handler.GetSignatureSize(); +} + +Expected SignExecutor::ValidateStreamTransition( + const common::OperationAction action, + const StreamOperationState currentState, + StreamOperationState& nextState) +{ + // Map the SIGN action to the generic stream operation used by the + // centralized state-transition validator. + handler::handler_utils::StreamOperation op{}; + if (action == handler::sign_handler_operations::SIGN_INIT) + { + op = handler::handler_utils::StreamOperation::kInit; + } + else if (action == handler::sign_handler_operations::SIGN_UPDATE) + { + op = handler::handler_utils::StreamOperation::kUpdate; + } + else if (action == handler::sign_handler_operations::SIGN_FINALIZE) + { + op = handler::handler_utils::StreamOperation::kFinalize; + } + else + { + return make_unexpected(DaemonErrorCode::kInvalidOperation); + } + const auto result = handler::handler_utils::ValidateStreamOperationSequence(currentState, op); + if (!result.has_value()) + { + return make_unexpected(result.error()); + } + nextState = result.value(); + return std::monostate{}; +} +} // namespace score::crypto::daemon::provider::score_provider::operations::sign diff --git a/score/crypto/src/daemon/provider/score_provider/operations/verify/BUILD b/score/crypto/src/daemon/provider/score_provider/operations/verify/BUILD new file mode 100644 index 000000000..442f0ae31 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/verify/BUILD @@ -0,0 +1,13 @@ +load("@rules_cc//cc:defs.bzl", "cc_library") +cc_library( + name = "score_verify_handler", + srcs = ["src/score_verify_handler.cpp", "src/verify_executor.cpp"], + hdrs = ["score_verify_handler.hpp", "verify_executor.hpp"], + visibility = ["//:__subpackages__"], + deps = [ + "//score/crypto/src/daemon/common", + "//score/crypto/src/daemon/provider/handler:handler_headers", + "//score/crypto/src/daemon/provider/handler:handler_utils_impl", + "//score/crypto/src/daemon/provider/handler:verify_handler_operations", + ], +) diff --git a/score/crypto/src/daemon/provider/score_provider/operations/verify/score_verify_handler.hpp b/score/crypto/src/daemon/provider/score_provider/operations/verify/score_verify_handler.hpp new file mode 100644 index 000000000..dd822cb7a --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/verify/score_verify_handler.hpp @@ -0,0 +1,144 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file score_verify_handler.hpp +/// @brief Provider-neutral base handler for verification operations. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_SCORE_PROVIDER_OPERATIONS_VERIFY_SCORE_VERIFY_HANDLER_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_SCORE_PROVIDER_OPERATIONS_VERIFY_SCORE_VERIFY_HANDLER_HPP + +#include "score/crypto/src/daemon/common/daemon_error.hpp" +#include "score/crypto/src/daemon/common/types.hpp" +#include "score/crypto/src/daemon/provider/handler/i_handler.hpp" +#include +#include +#include + +namespace score::crypto::daemon::provider::score_provider::operations::verify +{ +/// @brief Forward declaration of the verification-operation executor. +class VerifyExecutor; + +/// @brief Abstract base handler for verification operations under the score interface family. +/// +/// Implements the daemon's Handler interface by delegating Execute() to the +/// injected VerifyExecutor. Concrete score-interface providers (e.g. OpenSSL, IAV_Primula) +/// inherit from this class and override the typed verification methods. +/// +/// Typed methods default to kUnsupportedOperation so that a partially-implemented +/// provider compiles and returns a clear error at runtime. +/// +/// The handler owns the operation executor and stores the configured algorithm +/// and streaming state. +class ScoreVerifyHandler : public handler::Handler +{ + public: + using Sptr = std::shared_ptr; + + ScoreVerifyHandler() = delete; + + /// @brief Create a provider-neutral verification handler. + /// + /// Takes ownership of the operation executor and stores the selected + /// verification algorithm. + /// + /// @param executor Executor used to dispatch verification operations. + /// @param algorithm Algorithm identifier handled by this instance. + ScoreVerifyHandler(std::unique_ptr executor, const common::AlgorithmId algorithm); + ~ScoreVerifyHandler() override; + + /// @brief Delegates to the injected executor. + /// + /// @param operation Operation identifier containing the verification action. + /// @param request Operation parameters. + [[nodiscard]] Expected Execute( + const common::OperationIdentifier& operation, + common::RequestParameters& request) override; + + /// @brief Initialize the handler context and reset the stream state to IDLE. + /// + /// @param init_params Context initialization parameters. + [[nodiscard]] Expected InitializeContext( + const handler::InitializationParams& init_params) override; + + /// @brief Reset the intermediate verification stream state back to IDLE. + [[nodiscard]] Expected Reset() override; + + // ----------------------------------------------------------------------- + // Stream state management + // ----------------------------------------------------------------------- + + /// @brief Return the current verification stream state. + [[nodiscard]] common::StreamOperationState GetOperationState() const noexcept + { + return m_state; + } + + /// @brief Set the current verification stream state. + void SetOperationState(common::StreamOperationState state) noexcept + { + m_state = state; + } + + /// @brief Return the configured verification algorithm. + [[nodiscard]] const common::AlgorithmId& GetAlgorithm() const noexcept + { + return m_algorithm; + } + + // ----------------------------------------------------------------------- + // Typed verification operations — override in concrete provider handlers + // ----------------------------------------------------------------------- + + /// @brief Initialize a verification operation on an existing context. + /// + /// @param initial_data Optional data to include during initialization. + [[nodiscard]] virtual Expected InitVerify( + std::optional initial_data); + + /// @brief Add data to the active verification stream. + /// + /// @param data Message data to add to the verification. + [[nodiscard]] virtual Expected UpdateVerify( + const common::RequestParameter& data); + + /// @brief Finalize the verification and return the signature result. + /// + /// @param final_data Optional final data to add before verification. + /// @param output Optional signature or output buffer. + /// @return `true` if the signature is valid, `false` if it is invalid, or + /// a daemon error if the verification cannot be performed. + [[nodiscard]] virtual Expected FinalizeVerify( + std::optional final_data, + std::optional output); + + /// @brief Perform single-shot verification without streaming. + /// + /// @param data Message data to verify. + /// @param signature Signature to verify against the message data. + /// @return `true` if the signature is valid, `false` if it is invalid, or + /// a daemon error if the verification cannot be performed. + [[nodiscard]] virtual Expected SingleShotVerify( + const common::RequestParameter& data, + const common::RequestParameter& signature); + + protected: + common::AlgorithmId m_algorithm; ///< Algorithm handled by this instance. + common::StreamOperationState m_state{common::StreamOperationState::IDLE}; ///< Current streaming state. + + private: + std::unique_ptr m_executor; ///< Owns the operation dispatcher. +}; +} // namespace score::crypto::daemon::provider::score_provider::operations::verify + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_SCORE_PROVIDER_OPERATIONS_VERIFY_SCORE_VERIFY_HANDLER_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/operations/verify/src/score_verify_handler.cpp b/score/crypto/src/daemon/provider/score_provider/operations/verify/src/score_verify_handler.cpp new file mode 100644 index 000000000..66b1ce391 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/verify/src/score_verify_handler.cpp @@ -0,0 +1,91 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/operations/verify/score_verify_handler.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/verify/verify_executor.hpp" + +namespace score::crypto::daemon::provider::score_provider::operations::verify +{ + +// The handler owns the executor and stores the algorithm used by the provider. +ScoreVerifyHandler::ScoreVerifyHandler(std::unique_ptr executor, const common::AlgorithmId algorithm) + : m_algorithm{std::move(algorithm)}, m_executor{std::move(executor)} +{ +} + +ScoreVerifyHandler::~ScoreVerifyHandler() = default; + +Expected ScoreVerifyHandler::Execute( + const common::OperationIdentifier& operation, + common::RequestParameters& request) +{ + if (m_executor == nullptr) + { + // A missing executor indicates an invalid handler configuration. + return make_unexpected(common::DaemonErrorCode::kInternalError); + } + + // Delegate operation dispatch to the injected verification executor. + return m_executor->Execute(*this, operation, request); +} + +Expected ScoreVerifyHandler::InitializeContext( + const handler::InitializationParams& /*init_params*/) +{ + // Reset the streaming state when a new handler context is initialized. + m_state = common::StreamOperationState::IDLE; + return std::monostate{}; +} + +Expected ScoreVerifyHandler::Reset() +{ + // Reset the streaming state; provider-specific resources are reset by + // concrete handlers when they override this method. + m_state = common::StreamOperationState::IDLE; + return std::monostate{}; +} + +// --------------------------------------------------------------------------- +// Default typed operations — return unsupported unless overridden +// --------------------------------------------------------------------------- + +Expected ScoreVerifyHandler::InitVerify( + std::optional /*initial_data*/) +{ + return make_unexpected(common::DaemonErrorCode::kUnsupportedOperation); +} + +Expected ScoreVerifyHandler::UpdateVerify( + const common::RequestParameter& /*data*/) +{ + return make_unexpected(common::DaemonErrorCode::kUnsupportedOperation); +} + +Expected ScoreVerifyHandler::FinalizeVerify( + std::optional /*final_data*/, + std::optional /*output*/) +{ + // The base implementation reports an unsupported operation rather than + // false, which is reserved for an invalid signature after verification. + return make_unexpected(common::DaemonErrorCode::kUnsupportedOperation); +} + +Expected ScoreVerifyHandler::SingleShotVerify( + const common::RequestParameter& /*data*/, + const common::RequestParameter& /*signature*/) +{ + // The base implementation reports an unsupported operation rather than + // false, which is reserved for an invalid signature after verification. + return make_unexpected(common::DaemonErrorCode::kUnsupportedOperation); +} +} // namespace score::crypto::daemon::provider::score_provider::operations::verify diff --git a/score/crypto/src/daemon/provider/score_provider/operations/verify/src/verify_executor.cpp b/score/crypto/src/daemon/provider/score_provider/operations/verify/src/verify_executor.cpp new file mode 100644 index 000000000..08873f037 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/verify/src/verify_executor.cpp @@ -0,0 +1,244 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include "score/crypto/src/daemon/provider/score_provider/operations/verify/verify_executor.hpp" +#include "score/crypto/src/daemon/provider/handler/operations/verify_handler_operations.hpp" +#include "score/crypto/src/daemon/provider/handler/src/handler_utils.hpp" +#include "score/crypto/src/daemon/provider/score_provider/operations/verify/score_verify_handler.hpp" + +namespace score::crypto::daemon::provider::score_provider::operations::verify +{ +namespace handler = ::score::crypto::daemon::provider::handler; +using common::DaemonErrorCode; +using common::RequestParameters; +using common::ResponseParameters; +using common::StreamOperationState; + +Expected VerifyExecutor::Execute(ScoreVerifyHandler& handler, + const common::OperationIdentifier& operationId, + RequestParameters& request) +{ + // RESET does not participate in the streaming state machine. + if (operationId.operationAction == handler::verify_handler_operations::VERIFY_RESET) + { + auto result = ExecuteReset(handler, request); + if (!result.has_value()) + { + return make_unexpected(result.error()); + } + return ResponseParameters{}; + } + + // A single-shot verification is only valid while no streaming operation is active. + if (operationId.operationAction == handler::verify_handler_operations::VERIFY_SS) + { + StreamOperationState state = handler.GetOperationState(); + if (state != StreamOperationState::IDLE) + { + return make_unexpected(DaemonErrorCode::kOperationInProgress); + } + return ExecuteSingleShot(handler, request); + } + + // Streaming operations must follow the valid state-machine transition before + // the corresponding handler method is called. + StreamOperationState currentState = handler.GetOperationState(); + StreamOperationState nextState = StreamOperationState::IDLE; + const auto sequenceValidation = ValidateStreamTransition(operationId.operationAction, currentState, nextState); + if (!sequenceValidation.has_value()) + { + return make_unexpected(sequenceValidation.error()); + } + + // Finalization returns the verification result and updates the state only + // after successful handler execution. + if (operationId.operationAction == handler::verify_handler_operations::VERIFY_FINALIZE) + { + auto result = ExecuteFinalize(handler, request); + if (result.has_value()) + { + handler.SetOperationState(nextState); + } + return result; + } + + // Initialization and update return no response parameters. The stream state + // is advanced only when the handler accepts the operation. + + if (operationId.operationAction == handler::verify_handler_operations::VERIFY_FINALIZE) + { + auto result = ExecuteInit(handler, request); + if (result.has_value()) + { + handler.SetOperationState(nextState); + } + else + { + return make_unexpected(result.error()); + } + } + + if (operationId.operationAction == handler::verify_handler_operations::VERIFY_UPDATE) + { + auto result = ExecuteUpdate(handler, request); + if (result.has_value()) + { + handler.SetOperationState(nextState); + } + else + { + return make_unexpected(result.error()); + } + } + + const auto result = [&]() -> Expected { + if (operationId.operationAction == handler::verify_handler_operations::VERIFY_INIT) + { + return ExecuteInit(handler, request); + } + if (operationId.operationAction == handler::verify_handler_operations::VERIFY_UPDATE) + { + return ExecuteUpdate(handler, request); + } + return make_unexpected(DaemonErrorCode::kInvalidOperation); + }(); + + if (result.has_value()) + { + handler.SetOperationState(nextState); + } + else + { + return make_unexpected(result.error()); + } + + return ResponseParameters{}; +} + +Expected VerifyExecutor::ExecuteInit(ScoreVerifyHandler& handler, + RequestParameters& request) +{ + // Initialization data is optional and is forwarded when it has the + // expected byte-span type. + std::optional> initialData; + if (!request.empty()) + { + if (auto* buf = std::get_if>(&request[0])) + { + initialData.emplace(*buf); + } + } + return handler.InitVerify(initialData); +} + +Expected VerifyExecutor::ExecuteUpdate(ScoreVerifyHandler& handler, + RequestParameters& request) +{ + // UPDATE requires one input buffer containing data for the active stream. + if (request.empty()) + { + return make_unexpected(DaemonErrorCode::kInsufficientParameters); + } + + auto* buf = std::get_if>(&request[0]); + if (buf == nullptr) + { + return make_unexpected(DaemonErrorCode::kInvalidDataType); + } + + return handler.UpdateVerify(*buf); +} + +Expected VerifyExecutor::ExecuteFinalize(ScoreVerifyHandler& handler, + RequestParameters& request) +{ + // FINALIZE accepts the signature data and optional final streaming data. + std::optional> output; + if (!request.empty()) + { + if (auto* buf = std::get_if>(&request[0])) + { + output.emplace(*buf); + } + } + + std::optional> finalData; + if (request.size() > 1) + { + if (auto* buf = std::get_if>(&request[1])) + { + finalData.emplace(*buf); + } + } + + return handler.FinalizeVerify(output, finalData); +} + +Expected VerifyExecutor::ExecuteSingleShot(ScoreVerifyHandler& handler, + RequestParameters& request) +{ + // SINGLE-SHOT forwards the verification data and signature to the handler. + if (request.size() < 2U) + { + return make_unexpected(DaemonErrorCode::kInsufficientParameters); + } + + auto* data = std::get_if>(&request[0]); + if (data == nullptr) + { + return make_unexpected(DaemonErrorCode::kInvalidDataType); + } + + return handler.SingleShotVerify(*data, request[1]); +} + +Expected VerifyExecutor::ExecuteReset(ScoreVerifyHandler& handler, + RequestParameters& /*request*/) +{ + // RESET does not consume request parameters; the handler owns the reset logic. + return handler.Reset(); +} + +Expected VerifyExecutor::ValidateStreamTransition( + const common::OperationAction action, + const StreamOperationState currentState, + StreamOperationState& nextState) +{ + // Map the VERIFY action to the generic stream operation used by the + // centralized state-transition validator. + handler::handler_utils::StreamOperation op{}; + if (action == handler::verify_handler_operations::VERIFY_INIT) + { + op = handler::handler_utils::StreamOperation::kInit; + } + else if (action == handler::verify_handler_operations::VERIFY_UPDATE) + { + op = handler::handler_utils::StreamOperation::kUpdate; + } + else if (action == handler::verify_handler_operations::VERIFY_FINALIZE) + { + op = handler::handler_utils::StreamOperation::kFinalize; + } + else + { + return make_unexpected(DaemonErrorCode::kInvalidOperation); + } + const auto result = handler::handler_utils::ValidateStreamOperationSequence(currentState, op); + if (!result.has_value()) + { + return make_unexpected(result.error()); + } + nextState = result.value(); + return std::monostate{}; +} +} // namespace score::crypto::daemon::provider::score_provider::operations::verify diff --git a/score/crypto/src/daemon/provider/score_provider/operations/verify/verify_executor.hpp b/score/crypto/src/daemon/provider/score_provider/operations/verify/verify_executor.hpp new file mode 100644 index 000000000..0630508d1 --- /dev/null +++ b/score/crypto/src/daemon/provider/score_provider/operations/verify/verify_executor.hpp @@ -0,0 +1,111 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file verify_executor.hpp +/// @brief Operation dispatcher for provider-neutral verification handlers. + +#ifndef SCORE_CRYPTO_DAEMON_PROVIDER_SCORE_PROVIDER_OPERATIONS_VERIFY_VERIFY_EXECUTOR_HPP +#define SCORE_CRYPTO_DAEMON_PROVIDER_SCORE_PROVIDER_OPERATIONS_VERIFY_VERIFY_EXECUTOR_HPP + +#include "score/crypto/src/common/types.hpp" +#include "score/crypto/src/daemon/common/daemon_error.hpp" +#include "score/crypto/src/daemon/common/types.hpp" + +namespace score::crypto::daemon::provider::score_provider::operations::verify +{ +/// @brief Forward declaration of the provider-neutral verification handler. +class ScoreVerifyHandler; + +/// @brief Stateless dispatcher for provider-neutral verification operations. +/// +/// Validates operation requests and streaming state transitions, then delegates +/// each operation to the corresponding ScoreVerifyHandler method. The executor +/// does not store operation state; the state is maintained by the handler. +class VerifyExecutor final +{ + public: + /// @brief Execute one VERIFY operation. + /// + /// Dispatches the operation identified by the operation action to the + /// corresponding ScoreVerifyHandler method. + /// + /// @param handler Verification handler receiving the operation. + /// @param operation Operation identifier containing the verification action. + /// @param request Operation parameters. + /// @return Verification response, or a daemon error if the parameters, + /// operation, or stream state are invalid. + [[nodiscard]] Expected Execute( + ScoreVerifyHandler& handler, + const common::OperationIdentifier& operation, + common::RequestParameters& request); + + private: + /// @brief Execute the initialization step of a streaming verification. + /// + /// @param handler Verification handler receiving the operation. + /// @param request Optional initialization data. + /// @return Success, or a daemon error reported by the handler. + [[nodiscard]] Expected ExecuteInit(ScoreVerifyHandler& handler, + common::RequestParameters& request); + + /// @brief Add data to an active streaming verification. + /// + /// @param handler Verification handler receiving the operation. + /// @param request Request containing the data to be verified. + /// @return Success, or a daemon error if the request is invalid or the + /// handler rejects the operation. + [[nodiscard]] Expected ExecuteUpdate(ScoreVerifyHandler& handler, + common::RequestParameters& request); + + /// @brief Finalize a streaming verification. + /// + /// @param handler Verification handler receiving the operation. + /// @param request Signature and optional final data or output parameters. + /// @return Verification result, or a daemon error reported by the handler. + [[nodiscard]] Expected ExecuteFinalize( + ScoreVerifyHandler& handler, + common::RequestParameters& request); + + /// @brief Execute a single-shot verification operation. + /// + /// @param handler Verification handler receiving the operation. + /// @param request Verification data and signature parameters. + /// @return Verification result, or a daemon error if the request is invalid + /// or the handler rejects the operation. + [[nodiscard]] Expected ExecuteSingleShot( + ScoreVerifyHandler& handler, + common::RequestParameters& request); + + /// @brief Reset the verification handler to its initial stream state. + /// + /// @param handler Verification handler receiving the reset operation. + /// @param request Reset operation parameters, which are unused. + /// @return Success, or a daemon error reported by the handler. + [[nodiscard]] Expected ExecuteReset(ScoreVerifyHandler& handler, + common::RequestParameters& request); + + /// @brief Validate a streaming operation and determine its next state. + /// + /// @param action Streaming operation to validate. + /// @param currentState Current verification stream state. + /// @param nextState Receives the state resulting from the operation. + /// @return Success with the next state, or a daemon error for an invalid + /// operation or state transition. + [[nodiscard]] static Expected ValidateStreamTransition( + common::OperationAction action, + common::StreamOperationState currentState, + common::StreamOperationState& nextState); +}; +} // namespace score::crypto::daemon::provider::score_provider::operations::verify + +#endif // SCORE_CRYPTO_DAEMON_PROVIDER_SCORE_PROVIDER_OPERATIONS_VERIFY_VERIFY_EXECUTOR_HPP diff --git a/score/crypto/src/daemon/provider/score_provider/score_provider_config.hpp b/score/crypto/src/daemon/provider/score_provider/score_provider_config.hpp index 8b7478918..1f042df0d 100644 --- a/score/crypto/src/daemon/provider/score_provider/score_provider_config.hpp +++ b/score/crypto/src/daemon/provider/score_provider/score_provider_config.hpp @@ -39,7 +39,7 @@ struct ScoreProviderEntry { /// Provider name used to register and look up this provider in ProviderManager. std::string providerName{}; - /// Implementation tag that selects the concrete factory, e.g. "openssl". + /// Implementation tag that selects the concrete factory, e.g. "openssl" or "primula". std::string providerImpl{}; /// Provider type (SOFTWARE, HARDWARE, etc.) /// Note: Uses string to avoid including common/types.hpp in config header diff --git a/score/iav_primula/BUILD b/score/iav_primula/BUILD index c7c2aad84..69bf8a6e0 100644 --- a/score/iav_primula/BUILD +++ b/score/iav_primula/BUILD @@ -11,12 +11,32 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -load("@rules_rust//rust:defs.bzl", "rust_library") +load("@rules_rust//rust:defs.bzl", "rust_library", "rust_static_library") rust_library( name = "iav_primula", - srcs = ["src/main.rs"], + srcs = [ + "src/ffi.rs", + ], crate_name = "iav_primula", + crate_root = "src/ffi.rs", edition = "2021", visibility = ["//visibility:public"], ) + +rust_static_library( + name = "iav_primula_staticlib", + srcs = [ + "src/ffi.rs", + ], + crate_name = "iav_primula", + crate_root = "src/ffi.rs", + edition = "2021", + visibility = ["//visibility:public"], +) + +cc_library( + name = "iav_primula_ffi_headers", + hdrs = ["include/iav_primula_ffi.h"], + visibility = ["//visibility:public"], +) diff --git a/score/iav_primula/include/iav_primula_ffi.h b/score/iav_primula/include/iav_primula_ffi.h new file mode 100644 index 000000000..f84f3e4ab --- /dev/null +++ b/score/iav_primula/include/iav_primula_ffi.h @@ -0,0 +1,188 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +/// @file iav_primula_ffi.h +/// @brief Stable C ABI between the C++ daemon and the Rust PQC backend. + +#ifndef SCORE_IAV_PRIMULA_FFI_H +#define SCORE_IAV_PRIMULA_FFI_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/// @brief Status codes returned by the IAV-Primula C ABI. +/// +/// The numeric values are part of the stable ABI and must not be changed. +typedef enum iav_status +{ + IavStatusOk = 0, ///< The operation completed successfully. + IavStatusInvalidArgument = 1, ///< One or more arguments are invalid. + IavStatusBufferTooSmall = 2, ///< An output buffer cannot hold the result. + IavStatusUnsupportedAlgorithm = 3, ///< The requested algorithm is not supported. + IavStatusVerificationFailed = 4, ///< Verification completed and the signature is invalid. + IavStatusCryptoFailure = 5 ///< The backend failed to perform the cryptographic operation. +} iav_status; + +/// @brief Algorithms understood by the IAV-Primula C ABI. +/// +/// The numeric values are part of the stable ABI and must not be changed. +typedef enum iav_algorithm +{ + IavAlgorithmMlDsa44 = 1, ///< ML-DSA-44 signature algorithm. + IavAlgorithmMlDsa65 = 2, ///< ML-DSA-65 signature algorithm. + IavAlgorithmMlDsa87 = 3, ///< ML-DSA-87 signature algorithm. + IavAlgorithmMlKem512 = 10, ///< ML-KEM-512 key-encapsulation algorithm. + IavAlgorithmMlKem768 = 11, ///< ML-KEM-768 key-encapsulation algorithm. + IavAlgorithmMlKem1024 = 12 ///< ML-KEM-1024 key-encapsulation algorithm. +} iav_algorithm; + +/// @brief Opaque backend-owned key handle. +/// +/// The handle contents are private to the backend and must not be inspected +/// or modified by callers. Handles returned by generation functions must be +/// released with iav_key_destroy(). +typedef struct iav_primula_key_handle iav_primula_key_handle; + +// --------------------------------------------------------------------------- +// Signature key management +// --------------------------------------------------------------------------- + +/// @brief Generate a signature key pair. +/// +/// @param algorithm Signature algorithm to use. +/// @param key Output pointer receiving the generated key handle. +/// @return IavStatusOk on success, or an error status if generation fails. +iav_status iav_keypair_generate(iav_algorithm algorithm, iav_primula_key_handle** key); + +/// @brief Export the public key associated with a signature key handle. +/// +/// @param key Signature key handle owned by the caller. +/// @param output Caller-provided output buffer for the public key. +/// @param output_len Input buffer capacity and output length written. +/// @return IavStatusOk on success, IavStatusBufferTooSmall when the +/// output buffer is insufficient, or another error status. +iav_status iav_public_key_export(const iav_primula_key_handle* key, uint8_t* output, size_t* output_len); + +// --------------------------------------------------------------------------- +// Signature operations +// --------------------------------------------------------------------------- + +/// @brief Sign a message with a generated signature key. +/// +/// @param key Signature key handle owned by the caller. +/// @param message Message data to sign. +/// @param message_len Number of bytes in message. +/// @param signature Caller-provided output buffer for the signature. +/// @param signature_len Input buffer capacity and output signature length. +/// @return IavStatusOk on success, IavStatusBufferTooSmall when the +/// signature buffer is insufficient, or another error status. +iav_status iav_sign(const iav_primula_key_handle* key, + const uint8_t* message, + size_t message_len, + uint8_t* signature, + size_t* signature_len); + +/// @brief Verify a message signature. +/// +/// @param key Signature key handle owned by the caller. +/// @param message Message data to verify. +/// @param message_len Number of bytes in message. +/// @param signature Signature to verify. +/// @param signature_len Number of bytes in signature. +/// @return IavStatusOk when the signature is valid, +/// IavStatusVerificationFailed when it is invalid, or another +/// error status when verification cannot be performed. +iav_status iav_verify(const iav_primula_key_handle* key, + const uint8_t* message, + size_t message_len, + const uint8_t* signature, + size_t signature_len); + +// --------------------------------------------------------------------------- +// KEM key management +// --------------------------------------------------------------------------- + +/// @brief Generate a KEM key pair. +/// +/// @param algorithm KEM algorithm to use. +/// @param key Output pointer receiving the generated key handle. +/// @return IavStatusOk on success, or an error status if generation fails. +iav_status iav_kem_keypair_generate(iav_algorithm algorithm, iav_primula_key_handle** key); + +/// @brief Export the public key associated with a KEM key handle. +/// +/// @param key KEM key handle owned by the caller. +/// @param output Caller-provided output buffer for the public key. +/// @param output_len Input buffer capacity and output length written. +/// @return IavStatusOk on success, IavStatusBufferTooSmall when the +/// output buffer is insufficient, or another error status. +iav_status iav_kem_public_key_export(const iav_primula_key_handle* key, uint8_t* output, size_t* output_len); + +// --------------------------------------------------------------------------- +// KEM operations +// --------------------------------------------------------------------------- + +/// @brief Encapsulate a shared secret using a public KEM key. +/// +/// @param algorithm KEM algorithm to use. +/// @param public_key Public key used for encapsulation. +/// @param public_key_len Number of bytes in public_key. +/// @param ciphertext Caller-provided output buffer for the ciphertext. +/// @param ciphertext_len Input capacity and output ciphertext length. +/// @param shared_secret Caller-provided output buffer for the shared secret. +/// @param shared_secret_len Input capacity and output shared-secret length. +/// @return IavStatusOk on success, IavStatusBufferTooSmall when an +/// output buffer is insufficient, or another error status. +iav_status iav_kem_encapsulate(iav_algorithm algorithm, + const uint8_t* public_key, + size_t public_key_len, + uint8_t* ciphertext, + size_t* ciphertext_len, + uint8_t* shared_secret, + size_t* shared_secret_len); + +/// @brief Decapsulate a shared secret using a private KEM key. +/// +/// @param key KEM key handle owned by the caller. +/// @param ciphertext Ciphertext to decapsulate. +/// @param ciphertext_len Number of bytes in ciphertext. +/// @param shared_secret Caller-provided output buffer for the shared secret. +/// @param shared_secret_len Input capacity and output shared-secret length. +/// @return IavStatusOk on success, IavStatusBufferTooSmall when the +/// output buffer is insufficient, or another error status. +iav_status iav_kem_decapsulate(const iav_primula_key_handle* key, + const uint8_t* ciphertext, + size_t ciphertext_len, + uint8_t* shared_secret, + size_t* shared_secret_len); + +// --------------------------------------------------------------------------- +// Resource cleanup +// --------------------------------------------------------------------------- + +/// @brief Destroy a key handle and release its backend resources. +/// +/// The handle must not be used after this function returns. +/// +/// @param key Key handle previously returned by a key-generation function. +void iav_key_destroy(iav_primula_key_handle* key); + +#ifdef __cplusplus +} +#endif + +#endif // SCORE_IAV_PRIMULA_FFI_H diff --git a/score/iav_primula/src/ffi.rs b/score/iav_primula/src/ffi.rs new file mode 100644 index 000000000..ea22490e6 --- /dev/null +++ b/score/iav_primula/src/ffi.rs @@ -0,0 +1,206 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +//! Rust side of the stable C ABI for the IAV-Primula PQC backend. +//! +//! Cryptographic implementation types are intentionally not exposed to C++. +//! This module owns the opaque Rust key handle and translates failures to +//! stable `iav_status` values. The cryptographic entry points currently use +//! placeholder implementations and return `IavStatusUnsupportedAlgorithm`. + +use core::ffi::c_void; + +#[repr(C)] +/// Opaque key handle exposed through the C ABI. +/// +/// The handle contents are private to Rust and must not be accessed by C++ +/// callers. +pub struct iav_primula_key_handle { + _private: [u8; 0], +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +/// Status codes exchanged through the C ABI. +/// +/// The numeric values must remain synchronized with `iav_primula_ffi.h`. +pub enum iav_status { + IavStatusOk = 0, // Operation completed successfully. + IavStatusInvalidArgument = 1, // One or more arguments are invalid. + IavStatusBufferTooSmall = 2, // An output buffer cannot hold the result. + IavStatusUnsupportedAlgorithm = 3, // The requested algorithm is not supported. + IavStatusVerificationFailed = 4, // Verification completed and the signature is invalid. + IavStatusCryptoFailure = 5, // The backend failed during a cryptographic operation. +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +/// Algorithms exchanged through the C ABI. +/// +/// The numeric values must remain synchronized with `iav_primula_ffi.h`. +pub enum iav_algorithm { + IavAlgorithmMlDsa44 = 1, // ML-DSA-44 signature algorithm. + IavAlgorithmMlDsa65 = 2, // ML-DSA-65 signature algorithm. + IavAlgorithmMlDsa87 = 3, // ML-DSA-87 signature algorithm. + IavAlgorithmMlKem512 = 10, // ML-KEM-512 key-encapsulation algorithm. + IavAlgorithmMlKem768 = 11, // ML-KEM-768 key-encapsulation algorithm. + IavAlgorithmMlKem1024 = 12, // ML-KEM-1024 key-encapsulation algorithm. +} + +/// Return the status used by the currently unimplemented backend operations. +fn unsupported() -> iav_status { + iav_status::IavStatusUnsupportedAlgorithm +} + +// The `extern "C"` ABI and `no_mangle` attribute preserve the C-compatible +// calling convention and exported symbol names declared in iav_primula_ffi.h. + +// --------------------------------------------------------------------------- +// Signature key management +// --------------------------------------------------------------------------- + +/// Generate a signature key pair. +/// +/// This entry point is currently a placeholder and returns +/// `IavStatusUnsupportedAlgorithm`. +#[no_mangle] +pub extern "C" fn iav_keypair_generate( + _algorithm: iav_algorithm, + _key: *mut *mut iav_primula_key_handle, +) -> iav_status { + unsupported() +} + +/// Export a signature public key. +/// +/// This entry point is currently a placeholder and returns +/// `IavStatusUnsupportedAlgorithm`. +#[no_mangle] +pub extern "C" fn iav_public_key_export( + _key: *const iav_primula_key_handle, + _output: *mut u8, + _output_len: *mut usize, +) -> iav_status { + unsupported() +} + +// --------------------------------------------------------------------------- +// KEM key management +// --------------------------------------------------------------------------- + +/// Generate a KEM key pair. +/// +/// This entry point is currently a placeholder and returns +/// `IavStatusUnsupportedAlgorithm`. +#[no_mangle] +pub extern "C" fn iav_kem_keypair_generate( + _algorithm: iav_algorithm, + _key: *mut *mut iav_primula_key_handle, +) -> iav_status { + unsupported() +} + +/// Export a KEM public key. +/// +/// This entry point is currently a placeholder and returns +/// `IavStatusUnsupportedAlgorithm`. +#[no_mangle] +pub extern "C" fn iav_kem_public_key_export( + _key: *const iav_primula_key_handle, + _output: *mut u8, + _output_len: *mut usize, +) -> iav_status { + unsupported() +} + +// --------------------------------------------------------------------------- +// Signature operations +// --------------------------------------------------------------------------- + +/// Sign a message with a signature key. +/// +/// This entry point is currently a placeholder and returns +/// `IavStatusUnsupportedAlgorithm`. +#[no_mangle] +pub extern "C" fn iav_sign( + _key: *const iav_primula_key_handle, + _message: *const u8, + _message_len: usize, + _signature: *mut u8, + _signature_len: *mut usize, +) -> iav_status { + unsupported() +} + +/// Verify a message signature. +/// +/// This entry point is currently a placeholder and returns +/// `IavStatusUnsupportedAlgorithm`. +#[no_mangle] +pub extern "C" fn iav_verify( + _key: *const iav_primula_key_handle, + _message: *const u8, + _message_len: usize, + _signature: *const u8, + _signature_len: usize, +) -> iav_status { + unsupported() +} + +// --------------------------------------------------------------------------- +// KEM operations +// --------------------------------------------------------------------------- + +/// Encapsulate a shared secret using a public KEM key. +/// +/// This entry point is currently a placeholder and returns +/// `IavStatusUnsupportedAlgorithm`. +#[no_mangle] +pub extern "C" fn iav_kem_encapsulate( + _algorithm: iav_algorithm, + _public_key: *const u8, + _public_key_len: usize, + _ciphertext: *mut u8, + _ciphertext_len: *mut usize, + _shared_secret: *mut u8, + _shared_secret_len: *mut usize, +) -> iav_status { + unsupported() +} + +/// Decapsulate a shared secret using a private KEM key. +/// +/// This entry point is currently a placeholder and returns +/// `IavStatusUnsupportedAlgorithm`. +#[no_mangle] +pub extern "C" fn iav_kem_decapsulate( + _key: *const iav_primula_key_handle, + _ciphertext: *const u8, + _ciphertext_len: usize, + _shared_secret: *mut u8, + _shared_secret_len: *mut usize, +) -> iav_status { + unsupported() +} + +// --------------------------------------------------------------------------- +// Resource cleanup +// --------------------------------------------------------------------------- + +/// Destroy a key handle and release its backend resources. +#[no_mangle] +pub extern "C" fn iav_key_destroy(_key: *mut iav_primula_key_handle) {} + +/// Keep the opaque pointer type referenced without exposing its representation. +#[allow(dead_code)] +fn _opaque_pointer_marker(_: *const c_void) {} diff --git a/score/iav_primula/src/main.rs b/score/iav_primula/src/main.rs deleted file mode 100644 index e0f149a92..000000000 --- a/score/iav_primula/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -// ******************************************************************************* -// Copyright (c) 2026 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache License Version 2.0 which is available at -// -// -// SPDX-License-Identifier: Apache-2.0 -// ******************************************************************************* - -pub fn get_hello_message() -> &'static str { - "Hello World from iav_primula" -} diff --git a/score/iav_primula/tests/BUILD b/score/iav_primula/tests/BUILD index 1bf65a3d9..836673b15 100644 --- a/score/iav_primula/tests/BUILD +++ b/score/iav_primula/tests/BUILD @@ -14,8 +14,8 @@ load("@rules_rust//rust:defs.bzl", "rust_test") rust_test( - name = "hello_test", - srcs = ["hello_test.rs"], + name = "ffi_test", + srcs = ["ffi_test.rs"], edition = "2021", deps = ["//score/iav_primula"], ) diff --git a/score/iav_primula/tests/ffi_test.rs b/score/iav_primula/tests/ffi_test.rs new file mode 100644 index 000000000..d03aaf678 --- /dev/null +++ b/score/iav_primula/tests/ffi_test.rs @@ -0,0 +1,101 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +use iav_primula::{ + iav_algorithm, iav_key_destroy, iav_keypair_generate, iav_kem_decapsulate, + iav_kem_encapsulate, iav_kem_keypair_generate, iav_kem_public_key_export, + iav_public_key_export, iav_sign, iav_status, iav_verify, + iav_primula_key_handle, +}; + +#[test] +fn exported_operations_report_unsupported_until_backend_is_connected() { + // These are minimal placeholder values for the current stub operations: + // key remains null, length is a dummy size parameter, and byte provides a + // minimal message or data reference. + let mut key: *mut iav_primula_key_handle = core::ptr::null_mut(); + let mut length = 0usize; + let byte = 0u8; + + // Signature key management must return the stable unsupported status while + // the concrete implementation is not integrated. + assert_eq!( + iav_keypair_generate(iav_algorithm::IavAlgorithmMlDsa44, &mut key), + iav_status::IavStatusUnsupportedAlgorithm + ); + + assert_eq!( + iav_public_key_export(key, core::ptr::null_mut(), &mut length), + iav_status::IavStatusUnsupportedAlgorithm + ); + + // KEM key management follows the same stub contract. + assert_eq!( + iav_kem_keypair_generate(iav_algorithm::IavAlgorithmMlKem512, &mut key), + iav_status::IavStatusUnsupportedAlgorithm + ); + assert_eq!( + iav_kem_public_key_export(key, core::ptr::null_mut(), &mut length), + iav_status::IavStatusUnsupportedAlgorithm + ); + + // Signature operations use the same unsupported status until implemented. + assert_eq!( + iav_sign(key, &byte, 0, core::ptr::null_mut(), &mut length), + iav_status::IavStatusUnsupportedAlgorithm + ); + assert_eq!( + iav_verify(key, &byte, 0, &byte, 0), + iav_status::IavStatusUnsupportedAlgorithm + ); + + // KEM operations also remain unsupported in the current backend stub. + assert_eq!( + iav_kem_encapsulate( + iav_algorithm::IavAlgorithmMlKem512, + &byte, + 0, + core::ptr::null_mut(), + &mut length, + core::ptr::null_mut(), + &mut length, + ), + iav_status::IavStatusUnsupportedAlgorithm + ); + assert_eq!( + iav_kem_decapsulate(key, &byte, 0, core::ptr::null_mut(), &mut length), + iav_status::IavStatusUnsupportedAlgorithm + ); + + // Resource cleanup is intentionally a no-op for the current null/stub handle. + iav_key_destroy(key); +} + +#[test] +fn ffi_status_and_algorithm_values_are_stable() { + // Status values are part of the stable C ABI. + assert_eq!(iav_status::IavStatusOk as u32, 0); + assert_eq!(iav_status::IavStatusInvalidArgument as u32, 1); + assert_eq!(iav_status::IavStatusBufferTooSmall as u32, 2); + assert_eq!(iav_status::IavStatusUnsupportedAlgorithm as u32, 3); + assert_eq!(iav_status::IavStatusVerificationFailed as u32, 4); + assert_eq!(iav_status::IavStatusCryptoFailure as u32, 5); + + // Algorithm values must match the #[repr(C)] declarations in the C header. + assert_eq!(iav_algorithm::IavAlgorithmMlDsa44 as u32, 1); + assert_eq!(iav_algorithm::IavAlgorithmMlDsa65 as u32, 2); + assert_eq!(iav_algorithm::IavAlgorithmMlDsa87 as u32, 3); + assert_eq!(iav_algorithm::IavAlgorithmMlKem512 as u32, 10); + assert_eq!(iav_algorithm::IavAlgorithmMlKem768 as u32, 11); + assert_eq!(iav_algorithm::IavAlgorithmMlKem1024 as u32, 12); +} diff --git a/score/iav_primula/tests/hello_test.rs b/score/iav_primula/tests/hello_test.rs deleted file mode 100644 index b211f69cd..000000000 --- a/score/iav_primula/tests/hello_test.rs +++ /dev/null @@ -1,19 +0,0 @@ -// ******************************************************************************* -// Copyright (c) 2026 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache License Version 2.0 which is available at -// -// -// SPDX-License-Identifier: Apache-2.0 -// ******************************************************************************* - -use iav_primula::get_hello_message; - -#[test] -fn returns_expected_message() { - assert_eq!(get_hello_message(), "Hello World from iav_primula"); -} diff --git a/tests/iav_primula/BUILD b/tests/iav_primula/BUILD new file mode 100644 index 000000000..173878c63 --- /dev/null +++ b/tests/iav_primula/BUILD @@ -0,0 +1,17 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +test_suite( + name = "all", + tests = ["//score/iav_primula/tests:ffi_test"], +) From 31499c9033a93b3f61c21aa50edd1a84d194daba Mon Sep 17 00:00:00 2001 From: HeHa112 <113408507+HeHa112@users.noreply.github.com> Date: Wed, 16 Sep 2026 12:48:01 +0200 Subject: [PATCH 12/12] Dependabot openssl adjustment cancelled (#11) * Dependabot openssl adjustment cancelled * update bazel.lock --- MODULE.bazel.lock | 16 ++++++++-------- score/cryptoki/Cargo.lock | 5 +++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index ac47bca49..c5ff87190 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -10127,7 +10127,7 @@ "bzlTransitiveDigest": "dVzUYZOMCmY4S/2o7jFmWXqRvZ9gTYlmjacTOfwzCh4=", "usagesDigest": "Ze9h0U0ZkpTbTWuxhjsLol+EDFknrBAMj8LM8KIdJNA=", "recordedFileInputs": { - "@@//score/cryptoki/Cargo.lock": "ac208f5b8efdce599a051c15eca72499dfe596fdc1e20afb5ef1ef44c4f8da80", + "@@//score/cryptoki/Cargo.lock": "2c53826b0b1590d9a00c4189f812b3a3cd98d3124450e4c3363bdc87db73ca0e", "@@//score/cryptoki/Cargo.toml": "b2981096af4f28666df7e229de67ecfcbda89c9f24c200c1dc46c49982d25fcc" }, "recordedDirentsInputs": {}, @@ -10146,9 +10146,9 @@ "repoRuleId": "@@rules_rust+//crate_universe:extensions.bzl%_generate_repo", "attributes": { "contents": { - "BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files(\n [\n \"cargo-bazel.json\",\n \"crates.bzl\",\n \"defs.bzl\",\n ] + glob(\n allow_empty = True,\n include = [\"*.bazel\"],\n ),\n)\n\nfilegroup(\n name = \"srcs\",\n srcs = glob(\n allow_empty = True,\n include = [\n \"*.bazel\",\n \"*.bzl\",\n ],\n ),\n)\n\n# Workspace Member Dependencies\nalias(\n name = \"argon2-0.5.3\",\n actual = \"@crates__argon2-0.5.3//:argon2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"argon2\",\n actual = \"@crates__argon2-0.5.3//:argon2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dirs-5.0.1\",\n actual = \"@crates__dirs-5.0.1//:dirs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dirs\",\n actual = \"@crates__dirs-5.0.1//:dirs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libc-0.2.186\",\n actual = \"@crates__libc-0.2.186//:libc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libc\",\n actual = \"@crates__libc-0.2.186//:libc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"once_cell-1.21.4\",\n actual = \"@crates__once_cell-1.21.4//:once_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"once_cell\",\n actual = \"@crates__once_cell-1.21.4//:once_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"openssl-0.10.80\",\n actual = \"@crates__openssl-0.10.80//:openssl\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"openssl\",\n actual = \"@crates__openssl-0.10.80//:openssl\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parking_lot-0.12.5\",\n actual = \"@crates__parking_lot-0.12.5//:parking_lot\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parking_lot\",\n actual = \"@crates__parking_lot-0.12.5//:parking_lot\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parsec-client-0.16.0\",\n actual = \"@crates__parsec-client-0.16.0//:parsec_client\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parsec-client\",\n actual = \"@crates__parsec-client-0.16.0//:parsec_client\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde-1.0.228\",\n actual = \"@crates__serde-1.0.228//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde\",\n actual = \"@crates__serde-1.0.228//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json-1.0.150\",\n actual = \"@crates__serde_json-1.0.150//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json\",\n actual = \"@crates__serde_json-1.0.150//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serial_test-3.5.0\",\n actual = \"@crates__serial_test-3.5.0//:serial_test\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serial_test\",\n actual = \"@crates__serial_test-3.5.0//:serial_test\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tempfile-3.27.0\",\n actual = \"@crates__tempfile-3.27.0//:tempfile\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tempfile\",\n actual = \"@crates__tempfile-3.27.0//:tempfile\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"toml-0.8.19\",\n actual = \"@crates__toml-0.8.19//:toml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"toml\",\n actual = \"@crates__toml-0.8.19//:toml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"zeroize-1.8.2\",\n actual = \"@crates__zeroize-1.8.2//:zeroize\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"zeroize\",\n actual = \"@crates__zeroize-1.8.2//:zeroize\",\n tags = [\"manual\"],\n)\n", + "BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files(\n [\n \"cargo-bazel.json\",\n \"crates.bzl\",\n \"defs.bzl\",\n ] + glob(\n allow_empty = True,\n include = [\"*.bazel\"],\n ),\n)\n\nfilegroup(\n name = \"srcs\",\n srcs = glob(\n allow_empty = True,\n include = [\n \"*.bazel\",\n \"*.bzl\",\n ],\n ),\n)\n\n# Workspace Member Dependencies\nalias(\n name = \"argon2-0.5.3\",\n actual = \"@crates__argon2-0.5.3//:argon2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"argon2\",\n actual = \"@crates__argon2-0.5.3//:argon2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dirs-5.0.1\",\n actual = \"@crates__dirs-5.0.1//:dirs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dirs\",\n actual = \"@crates__dirs-5.0.1//:dirs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libc-0.2.186\",\n actual = \"@crates__libc-0.2.186//:libc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libc\",\n actual = \"@crates__libc-0.2.186//:libc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"once_cell-1.21.4\",\n actual = \"@crates__once_cell-1.21.4//:once_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"once_cell\",\n actual = \"@crates__once_cell-1.21.4//:once_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"openssl-0.10.68\",\n actual = \"@crates__openssl-0.10.68//:openssl\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"openssl\",\n actual = \"@crates__openssl-0.10.68//:openssl\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parking_lot-0.12.5\",\n actual = \"@crates__parking_lot-0.12.5//:parking_lot\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parking_lot\",\n actual = \"@crates__parking_lot-0.12.5//:parking_lot\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parsec-client-0.16.0\",\n actual = \"@crates__parsec-client-0.16.0//:parsec_client\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parsec-client\",\n actual = \"@crates__parsec-client-0.16.0//:parsec_client\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde-1.0.228\",\n actual = \"@crates__serde-1.0.228//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde\",\n actual = \"@crates__serde-1.0.228//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json-1.0.150\",\n actual = \"@crates__serde_json-1.0.150//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json\",\n actual = \"@crates__serde_json-1.0.150//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serial_test-3.5.0\",\n actual = \"@crates__serial_test-3.5.0//:serial_test\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serial_test\",\n actual = \"@crates__serial_test-3.5.0//:serial_test\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tempfile-3.27.0\",\n actual = \"@crates__tempfile-3.27.0//:tempfile\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tempfile\",\n actual = \"@crates__tempfile-3.27.0//:tempfile\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"toml-0.8.19\",\n actual = \"@crates__toml-0.8.19//:toml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"toml\",\n actual = \"@crates__toml-0.8.19//:toml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"zeroize-1.8.2\",\n actual = \"@crates__zeroize-1.8.2//:zeroize\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"zeroize\",\n actual = \"@crates__zeroize-1.8.2//:zeroize\",\n tags = [\"manual\"],\n)\n", "alias_rules.bzl": "\"\"\"Alias that transitions its target to `compilation_mode=opt`. Use `transition_alias=\"opt\"` to enable.\"\"\"\n\nload(\"@rules_cc//cc:defs.bzl\", \"CcInfo\")\nload(\"@rules_rust//rust:rust_common.bzl\", \"COMMON_PROVIDERS\")\n\ndef _transition_alias_impl(ctx):\n # `ctx.attr.actual` is a list of 1 item due to the transition\n providers = [ctx.attr.actual[0][provider] for provider in COMMON_PROVIDERS]\n if CcInfo in ctx.attr.actual[0]:\n providers.append(ctx.attr.actual[0][CcInfo])\n return providers\n\ndef _change_compilation_mode(compilation_mode):\n def _change_compilation_mode_impl(_settings, _attr):\n return {\n \"//command_line_option:compilation_mode\": compilation_mode,\n }\n\n return transition(\n implementation = _change_compilation_mode_impl,\n inputs = [],\n outputs = [\n \"//command_line_option:compilation_mode\",\n ],\n )\n\ndef _transition_alias_rule(compilation_mode):\n return rule(\n implementation = _transition_alias_impl,\n provides = COMMON_PROVIDERS,\n attrs = {\n \"actual\": attr.label(\n mandatory = True,\n doc = \"`rust_library()` target to transition to `compilation_mode=opt`.\",\n providers = COMMON_PROVIDERS,\n cfg = _change_compilation_mode(compilation_mode),\n ),\n \"_allowlist_function_transition\": attr.label(\n default = \"@bazel_tools//tools/allowlists/function_transition_allowlist\",\n ),\n },\n doc = \"Transitions a Rust library crate to the `compilation_mode=opt`.\",\n )\n\ntransition_alias_dbg = _transition_alias_rule(\"dbg\")\ntransition_alias_fastbuild = _transition_alias_rule(\"fastbuild\")\ntransition_alias_opt = _transition_alias_rule(\"opt\")\n", - "defs.bzl": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\"\"\"\n# `crates_repository` API\n\n- [aliases](#aliases)\n- [crate_deps](#crate_deps)\n- [all_crate_deps](#all_crate_deps)\n- [crate_repositories](#crate_repositories)\n\n\"\"\"\n\nload(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"new_git_repository\")\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\nload(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")\nload(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\nload(\"@rules_rust//crate_universe/private:local_crate_mirror.bzl\", \"local_crate_mirror\")\n\n###############################################################################\n# MACROS API\n###############################################################################\n\n# An identifier that represent common dependencies (unconditional).\n_COMMON_CONDITION = \"\"\n\ndef _flatten_dependency_maps(all_dependency_maps):\n \"\"\"Flatten a list of dependency maps into one dictionary.\n\n Dependency maps have the following structure:\n\n ```python\n DEPENDENCIES_MAP = {\n # The first key in the map is a Bazel package\n # name of the workspace this file is defined in.\n \"workspace_member_package\": {\n\n # Not all dependencies are supported for all platforms.\n # the condition key is the condition required to be true\n # on the host platform.\n \"condition\": {\n\n # An alias to a crate target. # The label of the crate target the\n # Aliases are only crate names. # package name refers to.\n \"package_name\": \"@full//:label\",\n }\n }\n }\n ```\n\n Args:\n all_dependency_maps (list): A list of dicts as described above\n\n Returns:\n dict: A dictionary as described above\n \"\"\"\n dependencies = {}\n\n for workspace_deps_map in all_dependency_maps:\n for pkg_name, conditional_deps_map in workspace_deps_map.items():\n if pkg_name not in dependencies:\n non_frozen_map = dict()\n for key, values in conditional_deps_map.items():\n non_frozen_map.update({key: dict(values.items())})\n dependencies.setdefault(pkg_name, non_frozen_map)\n continue\n\n for condition, deps_map in conditional_deps_map.items():\n # If the condition has not been recorded, do so and continue\n if condition not in dependencies[pkg_name]:\n dependencies[pkg_name].setdefault(condition, dict(deps_map.items()))\n continue\n\n # Alert on any miss-matched dependencies\n inconsistent_entries = []\n for crate_name, crate_label in deps_map.items():\n existing = dependencies[pkg_name][condition].get(crate_name)\n if existing and existing != crate_label:\n inconsistent_entries.append((crate_name, existing, crate_label))\n dependencies[pkg_name][condition].update({crate_name: crate_label})\n\n return dependencies\n\ndef crate_deps(deps, package_name = None):\n \"\"\"Finds the fully qualified label of the requested crates for the package where this macro is called.\n\n Args:\n deps (list): The desired list of crate targets.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()`.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if not deps:\n return []\n\n if package_name == None:\n package_name = native.package_name()\n\n # Join both sets of dependencies\n dependencies = _flatten_dependency_maps([\n _NORMAL_DEPENDENCIES,\n _NORMAL_DEV_DEPENDENCIES,\n _PROC_MACRO_DEPENDENCIES,\n _PROC_MACRO_DEV_DEPENDENCIES,\n _BUILD_DEPENDENCIES,\n _BUILD_PROC_MACRO_DEPENDENCIES,\n ]).pop(package_name, {})\n\n # Combine all conditional packages so we can easily index over a flat list\n # TODO: Perhaps this should actually return select statements and maintain\n # the conditionals of the dependencies\n flat_deps = {}\n for deps_set in dependencies.values():\n for crate_name, crate_label in deps_set.items():\n flat_deps.update({crate_name: crate_label})\n\n missing_crates = []\n crate_targets = []\n for crate_target in deps:\n if crate_target not in flat_deps:\n missing_crates.append(crate_target)\n else:\n crate_targets.append(flat_deps[crate_target])\n\n if missing_crates:\n fail(\"Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`\".format(\n missing_crates,\n package_name,\n dependencies,\n ))\n\n return crate_targets\n\ndef all_crate_deps(\n normal = False, \n normal_dev = False, \n proc_macro = False, \n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Finds the fully qualified label of all requested direct crate dependencies \\\n for the package where this macro is called.\n\n If no parameters are set, all normal dependencies are returned. Setting any one flag will\n otherwise impact the contents of the returned list.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list.\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_dependency_maps = []\n if normal:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n if normal_dev:\n all_dependency_maps.append(_NORMAL_DEV_DEPENDENCIES)\n if proc_macro:\n all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES)\n if proc_macro_dev:\n all_dependency_maps.append(_PROC_MACRO_DEV_DEPENDENCIES)\n if build:\n all_dependency_maps.append(_BUILD_DEPENDENCIES)\n if build_proc_macro:\n all_dependency_maps.append(_BUILD_PROC_MACRO_DEPENDENCIES)\n\n # Default to always using normal dependencies\n if not all_dependency_maps:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n\n dependencies = _flatten_dependency_maps(all_dependency_maps).pop(package_name, None)\n\n if not dependencies:\n if dependencies == None:\n fail(\"Tried to get all_crate_deps for package \" + package_name + \" but that package had no Cargo.toml file\")\n else:\n return []\n\n crate_deps = list(dependencies.pop(_COMMON_CONDITION, {}).values())\n for condition, deps in dependencies.items():\n crate_deps += selects.with_or({\n tuple(_CONDITIONS[condition]): deps.values(),\n \"//conditions:default\": [],\n })\n\n return crate_deps\n\ndef aliases(\n normal = False,\n normal_dev = False,\n proc_macro = False,\n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Produces a map of Crate alias names to their original label\n\n If no dependency kinds are specified, `normal` and `proc_macro` are used by default.\n Setting any one flag will otherwise determine the contents of the returned dict.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list..\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n dict: The aliases of all associated packages\n \"\"\"\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_aliases_maps = []\n if normal:\n all_aliases_maps.append(_NORMAL_ALIASES)\n if normal_dev:\n all_aliases_maps.append(_NORMAL_DEV_ALIASES)\n if proc_macro:\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n if proc_macro_dev:\n all_aliases_maps.append(_PROC_MACRO_DEV_ALIASES)\n if build:\n all_aliases_maps.append(_BUILD_ALIASES)\n if build_proc_macro:\n all_aliases_maps.append(_BUILD_PROC_MACRO_ALIASES)\n\n # Default to always using normal aliases\n if not all_aliases_maps:\n all_aliases_maps.append(_NORMAL_ALIASES)\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n\n aliases = _flatten_dependency_maps(all_aliases_maps).pop(package_name, None)\n\n if not aliases:\n return dict()\n\n common_items = aliases.pop(_COMMON_CONDITION, {}).items()\n\n # If there are only common items in the dictionary, immediately return them\n if not len(aliases.keys()) == 1:\n return dict(common_items)\n\n # Build a single select statement where each conditional has accounted for the\n # common set of aliases.\n crate_aliases = {\"//conditions:default\": dict(common_items)}\n for condition, deps in aliases.items():\n condition_triples = _CONDITIONS[condition]\n for triple in condition_triples:\n if triple in crate_aliases:\n crate_aliases[triple].update(deps)\n else:\n crate_aliases.update({triple: dict(deps.items() + common_items)})\n\n return select(crate_aliases)\n\n###############################################################################\n# WORKSPACE MEMBER DEPS AND ALIASES\n###############################################################################\n\n_NORMAL_DEPENDENCIES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n \"argon2\": Label(\"@crates//:argon2-0.5.3\"),\n \"dirs\": Label(\"@crates//:dirs-5.0.1\"),\n \"libc\": Label(\"@crates//:libc-0.2.186\"),\n \"once_cell\": Label(\"@crates//:once_cell-1.21.4\"),\n \"openssl\": Label(\"@crates//:openssl-0.10.80\"),\n \"parking_lot\": Label(\"@crates//:parking_lot-0.12.5\"),\n \"parsec-client\": Label(\"@crates//:parsec-client-0.16.0\"),\n \"serde\": Label(\"@crates//:serde-1.0.228\"),\n \"serde_json\": Label(\"@crates//:serde_json-1.0.150\"),\n \"tempfile\": Label(\"@crates//:tempfile-3.27.0\"),\n \"toml\": Label(\"@crates//:toml-0.8.19\"),\n \"zeroize\": Label(\"@crates//:zeroize-1.8.2\"),\n },\n },\n}\n\n\n_NORMAL_ALIASES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_NORMAL_DEV_DEPENDENCIES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n \"serial_test\": Label(\"@crates//:serial_test-3.5.0\"),\n },\n },\n}\n\n\n_NORMAL_DEV_ALIASES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_PROC_MACRO_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_PROC_MACRO_ALIASES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_PROC_MACRO_DEV_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_PROC_MACRO_DEV_ALIASES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_BUILD_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_BUILD_ALIASES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_ALIASES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_CONDITIONS = {\n \"aarch64-linux-android\": [],\n \"aarch64-pc-windows-gnullvm\": [],\n \"aarch64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\"],\n \"aarch64-unknown-nto-qnx800\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\"],\n \"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [],\n \"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), not(any(all(target_os = \\\"linux\\\", target_env = \\\"\\\"), getrandom_backend = \\\"custom\\\", getrandom_backend = \\\"linux_raw\\\", getrandom_backend = \\\"rdrand\\\", getrandom_backend = \\\"rndr\\\"))))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\"],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_os = \\\"linux\\\"))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\"],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_vendor = \\\"apple\\\"))\": [],\n \"cfg(all(target_arch = \\\"loongarch64\\\", target_os = \\\"linux\\\"))\": [],\n \"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"wasi\\\", target_env = \\\"p2\\\"))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"gnu\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86_64\\\", target_env = \\\"gnu\\\", not(target_abi = \\\"llvm\\\"), not(windows_raw_dylib)))\": [\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(all(target_arch = \\\"x86_64\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_os = \\\"uefi\\\", getrandom_backend = \\\"efi_rng\\\"))\": [],\n \"cfg(any())\": [],\n \"cfg(any(target_arch = \\\"x86\\\", target_arch = \\\"x86_64\\\"))\": [\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(any(target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"hurd\\\", target_os = \\\"illumos\\\", target_os = \\\"cygwin\\\", all(target_os = \\\"horizon\\\", target_arch = \\\"arm\\\")))\": [],\n \"cfg(any(target_os = \\\"haiku\\\", target_os = \\\"redox\\\", target_os = \\\"nto\\\", target_os = \\\"aix\\\"))\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\"],\n \"cfg(any(target_os = \\\"ios\\\", target_os = \\\"visionos\\\", target_os = \\\"watchos\\\", target_os = \\\"tvos\\\"))\": [],\n \"cfg(any(target_os = \\\"macos\\\", target_os = \\\"openbsd\\\", target_os = \\\"vita\\\", target_os = \\\"emscripten\\\"))\": [],\n \"cfg(any(unix, target_os = \\\"wasi\\\"))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(target_os = \\\"hermit\\\")\": [],\n \"cfg(target_os = \\\"netbsd\\\")\": [],\n \"cfg(target_os = \\\"redox\\\")\": [],\n \"cfg(target_os = \\\"solaris\\\")\": [],\n \"cfg(target_os = \\\"vxworks\\\")\": [],\n \"cfg(target_os = \\\"wasi\\\")\": [],\n \"cfg(unix)\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(windows)\": [],\n \"x86_64-pc-nto-qnx800\": [\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\"],\n \"x86_64-pc-windows-gnullvm\": [],\n \"x86_64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n}\n\n###############################################################################\n\ndef crate_repositories():\n \"\"\"A macro for defining repositories for all generated crates.\n\n Returns:\n A list of repos visible to the module through the module extension.\n \"\"\"\n maybe(\n http_archive,\n name = \"crates__aho-corasick-1.1.4\",\n sha256 = \"ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aho-corasick/1.1.4/download\"],\n strip_prefix = \"aho-corasick-1.1.4\",\n build_file = Label(\"@crates//crates:BUILD.aho-corasick-1.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anyhow-1.0.102\",\n sha256 = \"7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anyhow/1.0.102/download\"],\n strip_prefix = \"anyhow-1.0.102\",\n build_file = Label(\"@crates//crates:BUILD.anyhow-1.0.102.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__argon2-0.5.3\",\n sha256 = \"3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/argon2/0.5.3/download\"],\n strip_prefix = \"argon2-0.5.3\",\n build_file = Label(\"@crates//crates:BUILD.argon2-0.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__autocfg-1.5.1\",\n sha256 = \"f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/autocfg/1.5.1/download\"],\n strip_prefix = \"autocfg-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.autocfg-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__base64ct-1.6.0\",\n sha256 = \"8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/base64ct/1.6.0/download\"],\n strip_prefix = \"base64ct-1.6.0\",\n build_file = Label(\"@crates//crates:BUILD.base64ct-1.6.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bincode-1.3.3\",\n sha256 = \"b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bincode/1.3.3/download\"],\n strip_prefix = \"bincode-1.3.3\",\n build_file = Label(\"@crates//crates:BUILD.bincode-1.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bitflags-2.11.1\",\n sha256 = \"c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bitflags/2.11.1/download\"],\n strip_prefix = \"bitflags-2.11.1\",\n build_file = Label(\"@crates//crates:BUILD.bitflags-2.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__blake2-0.10.6\",\n sha256 = \"46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/blake2/0.10.6/download\"],\n strip_prefix = \"blake2-0.10.6\",\n build_file = Label(\"@crates//crates:BUILD.blake2-0.10.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__block-buffer-0.10.4\",\n sha256 = \"3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/block-buffer/0.10.4/download\"],\n strip_prefix = \"block-buffer-0.10.4\",\n build_file = Label(\"@crates//crates:BUILD.block-buffer-0.10.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytes-1.11.1\",\n sha256 = \"1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytes/1.11.1/download\"],\n strip_prefix = \"bytes-1.11.1\",\n build_file = Label(\"@crates//crates:BUILD.bytes-1.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cc-1.2.63\",\n sha256 = \"556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cc/1.2.63/download\"],\n strip_prefix = \"cc-1.2.63\",\n build_file = Label(\"@crates//crates:BUILD.cc-1.2.63.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg-if-1.0.4\",\n sha256 = \"9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg-if/1.0.4/download\"],\n strip_prefix = \"cfg-if-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.cfg-if-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cmake-0.1.58\",\n sha256 = \"c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cmake/0.1.58/download\"],\n strip_prefix = \"cmake-0.1.58\",\n build_file = Label(\"@crates//crates:BUILD.cmake-0.1.58.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cpufeatures-0.2.17\",\n sha256 = \"59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cpufeatures/0.2.17/download\"],\n strip_prefix = \"cpufeatures-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.cpufeatures-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crypto-common-0.1.7\",\n sha256 = \"78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crypto-common/0.1.7/download\"],\n strip_prefix = \"crypto-common-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.crypto-common-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__derivative-2.2.0\",\n sha256 = \"fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/derivative/2.2.0/download\"],\n strip_prefix = \"derivative-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.derivative-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__digest-0.10.7\",\n sha256 = \"9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/digest/0.10.7/download\"],\n strip_prefix = \"digest-0.10.7\",\n build_file = Label(\"@crates//crates:BUILD.digest-0.10.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dirs-5.0.1\",\n sha256 = \"44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dirs/5.0.1/download\"],\n strip_prefix = \"dirs-5.0.1\",\n build_file = Label(\"@crates//crates:BUILD.dirs-5.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dirs-sys-0.4.1\",\n sha256 = \"520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dirs-sys/0.4.1/download\"],\n strip_prefix = \"dirs-sys-0.4.1\",\n build_file = Label(\"@crates//crates:BUILD.dirs-sys-0.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__displaydoc-0.2.6\",\n sha256 = \"1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/displaydoc/0.2.6/download\"],\n strip_prefix = \"displaydoc-0.2.6\",\n build_file = Label(\"@crates//crates:BUILD.displaydoc-0.2.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__either-1.16.0\",\n sha256 = \"91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/either/1.16.0/download\"],\n strip_prefix = \"either-1.16.0\",\n build_file = Label(\"@crates//crates:BUILD.either-1.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__equivalent-1.0.2\",\n sha256 = \"877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/equivalent/1.0.2/download\"],\n strip_prefix = \"equivalent-1.0.2\",\n build_file = Label(\"@crates//crates:BUILD.equivalent-1.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__errno-0.3.14\",\n sha256 = \"39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/errno/0.3.14/download\"],\n strip_prefix = \"errno-0.3.14\",\n build_file = Label(\"@crates//crates:BUILD.errno-0.3.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fastrand-2.4.1\",\n sha256 = \"9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fastrand/2.4.1/download\"],\n strip_prefix = \"fastrand-2.4.1\",\n build_file = Label(\"@crates//crates:BUILD.fastrand-2.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__find-msvc-tools-0.1.9\",\n sha256 = \"5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/find-msvc-tools/0.1.9/download\"],\n strip_prefix = \"find-msvc-tools-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.find-msvc-tools-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-0.3.2\",\n sha256 = \"f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types/0.3.2/download\"],\n strip_prefix = \"foreign-types-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-shared-0.1.1\",\n sha256 = \"00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types-shared/0.1.1/download\"],\n strip_prefix = \"foreign-types-shared-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-shared-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__form_urlencoded-1.2.2\",\n sha256 = \"cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/form_urlencoded/1.2.2/download\"],\n strip_prefix = \"form_urlencoded-1.2.2\",\n build_file = Label(\"@crates//crates:BUILD.form_urlencoded-1.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-core-0.3.32\",\n sha256 = \"7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-core/0.3.32/download\"],\n strip_prefix = \"futures-core-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-core-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-executor-0.3.32\",\n sha256 = \"baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-executor/0.3.32/download\"],\n strip_prefix = \"futures-executor-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-executor-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-task-0.3.32\",\n sha256 = \"037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-task/0.3.32/download\"],\n strip_prefix = \"futures-task-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-task-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-util-0.3.32\",\n sha256 = \"389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-util/0.3.32/download\"],\n strip_prefix = \"futures-util-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-util-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__generic-array-0.14.7\",\n sha256 = \"85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/generic-array/0.14.7/download\"],\n strip_prefix = \"generic-array-0.14.7\",\n build_file = Label(\"@crates//crates:BUILD.generic-array-0.14.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.2.17\",\n sha256 = \"ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.2.17/download\"],\n strip_prefix = \"getrandom-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.3.4\",\n sha256 = \"899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.3.4/download\"],\n strip_prefix = \"getrandom-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.14.5\",\n sha256 = \"e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.14.5/download\"],\n strip_prefix = \"hashbrown-0.14.5\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.14.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_collections-1.5.0\",\n sha256 = \"db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_collections/1.5.0/download\"],\n strip_prefix = \"icu_collections-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_collections-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locid-1.5.0\",\n sha256 = \"13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locid/1.5.0/download\"],\n strip_prefix = \"icu_locid-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locid-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locid_transform-1.5.0\",\n sha256 = \"01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locid_transform/1.5.0/download\"],\n strip_prefix = \"icu_locid_transform-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locid_transform-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locid_transform_data-1.5.1\",\n sha256 = \"7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locid_transform_data/1.5.1/download\"],\n strip_prefix = \"icu_locid_transform_data-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_locid_transform_data-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_normalizer-1.5.0\",\n sha256 = \"19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_normalizer/1.5.0/download\"],\n strip_prefix = \"icu_normalizer-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_normalizer-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_normalizer_data-1.5.1\",\n sha256 = \"c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_normalizer_data/1.5.1/download\"],\n strip_prefix = \"icu_normalizer_data-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_normalizer_data-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_properties-1.5.1\",\n sha256 = \"93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_properties/1.5.1/download\"],\n strip_prefix = \"icu_properties-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_properties-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_properties_data-1.5.1\",\n sha256 = \"85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_properties_data/1.5.1/download\"],\n strip_prefix = \"icu_properties_data-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_properties_data-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_provider-1.5.0\",\n sha256 = \"6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_provider/1.5.0/download\"],\n strip_prefix = \"icu_provider-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_provider-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_provider_macros-1.5.0\",\n sha256 = \"1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_provider_macros/1.5.0/download\"],\n strip_prefix = \"icu_provider_macros-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_provider_macros-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__idna-1.0.3\",\n sha256 = \"686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/idna/1.0.3/download\"],\n strip_prefix = \"idna-1.0.3\",\n build_file = Label(\"@crates//crates:BUILD.idna-1.0.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__idna_adapter-1.2.0\",\n sha256 = \"daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/idna_adapter/1.2.0/download\"],\n strip_prefix = \"idna_adapter-1.2.0\",\n build_file = Label(\"@crates//crates:BUILD.idna_adapter-1.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__indexmap-2.0.0\",\n sha256 = \"d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/indexmap/2.0.0/download\"],\n strip_prefix = \"indexmap-2.0.0\",\n build_file = Label(\"@crates//crates:BUILD.indexmap-2.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itertools-0.10.5\",\n sha256 = \"b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itertools/0.10.5/download\"],\n strip_prefix = \"itertools-0.10.5\",\n build_file = Label(\"@crates//crates:BUILD.itertools-0.10.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itoa-1.0.18\",\n sha256 = \"8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itoa/1.0.18/download\"],\n strip_prefix = \"itoa-1.0.18\",\n build_file = Label(\"@crates//crates:BUILD.itoa-1.0.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libc-0.2.186\",\n sha256 = \"68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libc/0.2.186/download\"],\n strip_prefix = \"libc-0.2.186\",\n build_file = Label(\"@crates//crates:BUILD.libc-0.2.186.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libredox-0.1.17\",\n sha256 = \"f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libredox/0.1.17/download\"],\n strip_prefix = \"libredox-0.1.17\",\n build_file = Label(\"@crates//crates:BUILD.libredox-0.1.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__linux-raw-sys-0.12.1\",\n sha256 = \"32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/linux-raw-sys/0.12.1/download\"],\n strip_prefix = \"linux-raw-sys-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.linux-raw-sys-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__litemap-0.7.5\",\n sha256 = \"23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/litemap/0.7.5/download\"],\n strip_prefix = \"litemap-0.7.5\",\n build_file = Label(\"@crates//crates:BUILD.litemap-0.7.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__lock_api-0.4.14\",\n sha256 = \"224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/lock_api/0.4.14/download\"],\n strip_prefix = \"lock_api-0.4.14\",\n build_file = Label(\"@crates//crates:BUILD.lock_api-0.4.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__log-0.4.30\",\n sha256 = \"616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/log/0.4.30/download\"],\n strip_prefix = \"log-0.4.30\",\n build_file = Label(\"@crates//crates:BUILD.log-0.4.30.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memchr-2.8.1\",\n sha256 = \"6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memchr/2.8.1/download\"],\n strip_prefix = \"memchr-2.8.1\",\n build_file = Label(\"@crates//crates:BUILD.memchr-2.8.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-0.4.3\",\n sha256 = \"35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num/0.4.3/download\"],\n strip_prefix = \"num-0.4.3\",\n build_file = Label(\"@crates//crates:BUILD.num-0.4.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-bigint-0.4.6\",\n sha256 = \"a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-bigint/0.4.6/download\"],\n strip_prefix = \"num-bigint-0.4.6\",\n build_file = Label(\"@crates//crates:BUILD.num-bigint-0.4.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-complex-0.4.6\",\n sha256 = \"73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-complex/0.4.6/download\"],\n strip_prefix = \"num-complex-0.4.6\",\n build_file = Label(\"@crates//crates:BUILD.num-complex-0.4.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-derive-0.4.2\",\n sha256 = \"ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-derive/0.4.2/download\"],\n strip_prefix = \"num-derive-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.num-derive-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-integer-0.1.46\",\n sha256 = \"7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-integer/0.1.46/download\"],\n strip_prefix = \"num-integer-0.1.46\",\n build_file = Label(\"@crates//crates:BUILD.num-integer-0.1.46.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-iter-0.1.45\",\n sha256 = \"1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-iter/0.1.45/download\"],\n strip_prefix = \"num-iter-0.1.45\",\n build_file = Label(\"@crates//crates:BUILD.num-iter-0.1.45.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-rational-0.4.2\",\n sha256 = \"f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-rational/0.4.2/download\"],\n strip_prefix = \"num-rational-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.num-rational-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-traits-0.2.19\",\n sha256 = \"071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-traits/0.2.19/download\"],\n strip_prefix = \"num-traits-0.2.19\",\n build_file = Label(\"@crates//crates:BUILD.num-traits-0.2.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__once_cell-1.21.4\",\n sha256 = \"9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/once_cell/1.21.4/download\"],\n strip_prefix = \"once_cell-1.21.4\",\n build_file = Label(\"@crates//crates:BUILD.once_cell-1.21.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__openssl-0.10.80\",\n sha256 = \"a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/openssl/0.10.80/download\"],\n strip_prefix = \"openssl-0.10.80\",\n build_file = Label(\"@crates//crates:BUILD.openssl-0.10.80.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__openssl-macros-0.1.1\",\n sha256 = \"a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/openssl-macros/0.1.1/download\"],\n strip_prefix = \"openssl-macros-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.openssl-macros-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__openssl-sys-0.9.116\",\n patch_args = [\n \"-p1\",\n ],\n patches = [\n \"@@//third_party/patches:openssl_sys_build_rs.patch\",\n ],\n sha256 = \"f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/openssl-sys/0.9.116/download\"],\n strip_prefix = \"openssl-sys-0.9.116\",\n build_file = Label(\"@crates//crates:BUILD.openssl-sys-0.9.116.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__option-ext-0.2.0\",\n sha256 = \"04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/option-ext/0.2.0/download\"],\n strip_prefix = \"option-ext-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.option-ext-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking_lot-0.12.5\",\n sha256 = \"93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking_lot/0.12.5/download\"],\n strip_prefix = \"parking_lot-0.12.5\",\n build_file = Label(\"@crates//crates:BUILD.parking_lot-0.12.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking_lot_core-0.9.12\",\n sha256 = \"2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking_lot_core/0.9.12/download\"],\n strip_prefix = \"parking_lot_core-0.9.12\",\n build_file = Label(\"@crates//crates:BUILD.parking_lot_core-0.9.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parsec-client-0.16.0\",\n sha256 = \"a36f9d8e27166cf0586913812454174286e094d594cc8b28d8a8d02d64406bbc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parsec-client/0.16.0/download\"],\n strip_prefix = \"parsec-client-0.16.0\",\n build_file = Label(\"@crates//crates:BUILD.parsec-client-0.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parsec-interface-0.29.1\",\n sha256 = \"cc706e09209b30f10baa35709d41b9cc01d4931b21c00679f59db96cd1650add\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parsec-interface/0.29.1/download\"],\n strip_prefix = \"parsec-interface-0.29.1\",\n build_file = Label(\"@crates//crates:BUILD.parsec-interface-0.29.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__password-hash-0.5.0\",\n sha256 = \"346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/password-hash/0.5.0/download\"],\n strip_prefix = \"password-hash-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.password-hash-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__percent-encoding-2.3.2\",\n sha256 = \"9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/percent-encoding/2.3.2/download\"],\n strip_prefix = \"percent-encoding-2.3.2\",\n build_file = Label(\"@crates//crates:BUILD.percent-encoding-2.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pin-project-lite-0.2.17\",\n sha256 = \"a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pin-project-lite/0.2.17/download\"],\n strip_prefix = \"pin-project-lite-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.pin-project-lite-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pkg-config-0.3.33\",\n sha256 = \"19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pkg-config/0.3.33/download\"],\n strip_prefix = \"pkg-config-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.pkg-config-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__proc-macro2-1.0.106\",\n sha256 = \"8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/proc-macro2/1.0.106/download\"],\n strip_prefix = \"proc-macro2-1.0.106\",\n build_file = Label(\"@crates//crates:BUILD.proc-macro2-1.0.106.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__prost-0.9.0\",\n sha256 = \"444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/prost/0.9.0/download\"],\n strip_prefix = \"prost-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.prost-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__prost-derive-0.9.0\",\n sha256 = \"f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/prost-derive/0.9.0/download\"],\n strip_prefix = \"prost-derive-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.prost-derive-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__psa-crypto-0.12.0\",\n sha256 = \"89c2256e525b9a45ec3bbb3382a43dd8809240279e0aab8ea7ee220e9295445b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/psa-crypto/0.12.0/download\"],\n strip_prefix = \"psa-crypto-0.12.0\",\n build_file = Label(\"@crates//crates:BUILD.psa-crypto-0.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__psa-crypto-sys-0.12.0\",\n sha256 = \"f170cac3a328e1678916b276067ec170a5a51db1b9b8b4c00b44c2839819a963\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/psa-crypto-sys/0.12.0/download\"],\n strip_prefix = \"psa-crypto-sys-0.12.0\",\n build_file = Label(\"@crates//crates:BUILD.psa-crypto-sys-0.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quote-1.0.45\",\n sha256 = \"41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quote/1.0.45/download\"],\n strip_prefix = \"quote-1.0.45\",\n build_file = Label(\"@crates//crates:BUILD.quote-1.0.45.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__r-efi-5.3.0\",\n sha256 = \"69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/r-efi/5.3.0/download\"],\n strip_prefix = \"r-efi-5.3.0\",\n build_file = Label(\"@crates//crates:BUILD.r-efi-5.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_core-0.6.4\",\n sha256 = \"ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_core/0.6.4/download\"],\n strip_prefix = \"rand_core-0.6.4\",\n build_file = Label(\"@crates//crates:BUILD.rand_core-0.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__redox_syscall-0.5.18\",\n sha256 = \"ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/redox_syscall/0.5.18/download\"],\n strip_prefix = \"redox_syscall-0.5.18\",\n build_file = Label(\"@crates//crates:BUILD.redox_syscall-0.5.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__redox_users-0.4.6\",\n sha256 = \"ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/redox_users/0.4.6/download\"],\n strip_prefix = \"redox_users-0.4.6\",\n build_file = Label(\"@crates//crates:BUILD.redox_users-0.4.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-1.12.3\",\n sha256 = \"e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex/1.12.3/download\"],\n strip_prefix = \"regex-1.12.3\",\n build_file = Label(\"@crates//crates:BUILD.regex-1.12.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-automata-0.4.14\",\n sha256 = \"6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-automata/0.4.14/download\"],\n strip_prefix = \"regex-automata-0.4.14\",\n build_file = Label(\"@crates//crates:BUILD.regex-automata-0.4.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-syntax-0.8.10\",\n sha256 = \"dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-syntax/0.8.10/download\"],\n strip_prefix = \"regex-syntax-0.8.10\",\n build_file = Label(\"@crates//crates:BUILD.regex-syntax-0.8.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustix-1.1.4\",\n sha256 = \"b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustix/1.1.4/download\"],\n strip_prefix = \"rustix-1.1.4\",\n build_file = Label(\"@crates//crates:BUILD.rustix-1.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__same-file-1.0.6\",\n sha256 = \"93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/same-file/1.0.6/download\"],\n strip_prefix = \"same-file-1.0.6\",\n build_file = Label(\"@crates//crates:BUILD.same-file-1.0.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__scopeguard-1.2.0\",\n sha256 = \"94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/scopeguard/1.2.0/download\"],\n strip_prefix = \"scopeguard-1.2.0\",\n build_file = Label(\"@crates//crates:BUILD.scopeguard-1.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__secrecy-0.8.0\",\n sha256 = \"9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/secrecy/0.8.0/download\"],\n strip_prefix = \"secrecy-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.secrecy-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde-1.0.228\",\n sha256 = \"9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde/1.0.228/download\"],\n strip_prefix = \"serde-1.0.228\",\n build_file = Label(\"@crates//crates:BUILD.serde-1.0.228.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_core-1.0.228\",\n sha256 = \"41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_core/1.0.228/download\"],\n strip_prefix = \"serde_core-1.0.228\",\n build_file = Label(\"@crates//crates:BUILD.serde_core-1.0.228.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_derive-1.0.228\",\n sha256 = \"d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_derive/1.0.228/download\"],\n strip_prefix = \"serde_derive-1.0.228\",\n build_file = Label(\"@crates//crates:BUILD.serde_derive-1.0.228.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_json-1.0.150\",\n sha256 = \"e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_json/1.0.150/download\"],\n strip_prefix = \"serde_json-1.0.150\",\n build_file = Label(\"@crates//crates:BUILD.serde_json-1.0.150.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_spanned-0.6.9\",\n sha256 = \"bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_spanned/0.6.9/download\"],\n strip_prefix = \"serde_spanned-0.6.9\",\n build_file = Label(\"@crates//crates:BUILD.serde_spanned-0.6.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serial_test-3.5.0\",\n sha256 = \"699f4197115b8a7e7ff19c9a315a4bd6fffec26cc4626ef45ecaea389e081c6d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serial_test/3.5.0/download\"],\n strip_prefix = \"serial_test-3.5.0\",\n build_file = Label(\"@crates//crates:BUILD.serial_test-3.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serial_test_derive-3.5.0\",\n sha256 = \"94e153fc76e1c6a068703d6d29c508a0b15c061c4b7e43da59cc097bc342673c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serial_test_derive/3.5.0/download\"],\n strip_prefix = \"serial_test_derive-3.5.0\",\n build_file = Label(\"@crates//crates:BUILD.serial_test_derive-3.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__shlex-2.0.1\",\n sha256 = \"f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/shlex/2.0.1/download\"],\n strip_prefix = \"shlex-2.0.1\",\n build_file = Label(\"@crates//crates:BUILD.shlex-2.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__slab-0.4.12\",\n sha256 = \"0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/slab/0.4.12/download\"],\n strip_prefix = \"slab-0.4.12\",\n build_file = Label(\"@crates//crates:BUILD.slab-0.4.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__smallvec-1.15.1\",\n sha256 = \"67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/smallvec/1.15.1/download\"],\n strip_prefix = \"smallvec-1.15.1\",\n build_file = Label(\"@crates//crates:BUILD.smallvec-1.15.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__stable_deref_trait-1.2.1\",\n sha256 = \"6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/stable_deref_trait/1.2.1/download\"],\n strip_prefix = \"stable_deref_trait-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.stable_deref_trait-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__subtle-2.6.1\",\n sha256 = \"13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/subtle/2.6.1/download\"],\n strip_prefix = \"subtle-2.6.1\",\n build_file = Label(\"@crates//crates:BUILD.subtle-2.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-1.0.109\",\n sha256 = \"72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/1.0.109/download\"],\n strip_prefix = \"syn-1.0.109\",\n build_file = Label(\"@crates//crates:BUILD.syn-1.0.109.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-2.0.117\",\n sha256 = \"e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/2.0.117/download\"],\n strip_prefix = \"syn-2.0.117\",\n build_file = Label(\"@crates//crates:BUILD.syn-2.0.117.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__synstructure-0.13.2\",\n sha256 = \"728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/synstructure/0.13.2/download\"],\n strip_prefix = \"synstructure-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.synstructure-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tempfile-3.27.0\",\n sha256 = \"32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tempfile/3.27.0/download\"],\n strip_prefix = \"tempfile-3.27.0\",\n build_file = Label(\"@crates//crates:BUILD.tempfile-3.27.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-1.0.69\",\n sha256 = \"b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror/1.0.69/download\"],\n strip_prefix = \"thiserror-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-impl-1.0.69\",\n sha256 = \"4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror-impl/1.0.69/download\"],\n strip_prefix = \"thiserror-impl-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-impl-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tinystr-0.7.6\",\n sha256 = \"9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tinystr/0.7.6/download\"],\n strip_prefix = \"tinystr-0.7.6\",\n build_file = Label(\"@crates//crates:BUILD.tinystr-0.7.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml-0.8.19\",\n sha256 = \"a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml/0.8.19/download\"],\n strip_prefix = \"toml-0.8.19\",\n build_file = Label(\"@crates//crates:BUILD.toml-0.8.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_datetime-0.6.11\",\n sha256 = \"22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_datetime/0.6.11/download\"],\n strip_prefix = \"toml_datetime-0.6.11\",\n build_file = Label(\"@crates//crates:BUILD.toml_datetime-0.6.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_edit-0.22.20\",\n sha256 = \"583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_edit/0.22.20/download\"],\n strip_prefix = \"toml_edit-0.22.20\",\n build_file = Label(\"@crates//crates:BUILD.toml_edit-0.22.20.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__typenum-1.20.1\",\n sha256 = \"b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/typenum/1.20.1/download\"],\n strip_prefix = \"typenum-1.20.1\",\n build_file = Label(\"@crates//crates:BUILD.typenum-1.20.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-ident-1.0.24\",\n sha256 = \"e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-ident/1.0.24/download\"],\n strip_prefix = \"unicode-ident-1.0.24\",\n build_file = Label(\"@crates//crates:BUILD.unicode-ident-1.0.24.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__url-2.5.4\",\n sha256 = \"32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/url/2.5.4/download\"],\n strip_prefix = \"url-2.5.4\",\n build_file = Label(\"@crates//crates:BUILD.url-2.5.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf16_iter-1.0.5\",\n sha256 = \"c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf16_iter/1.0.5/download\"],\n strip_prefix = \"utf16_iter-1.0.5\",\n build_file = Label(\"@crates//crates:BUILD.utf16_iter-1.0.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf8_iter-1.0.4\",\n sha256 = \"b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf8_iter/1.0.4/download\"],\n strip_prefix = \"utf8_iter-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.utf8_iter-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uuid-0.8.2\",\n sha256 = \"bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uuid/0.8.2/download\"],\n strip_prefix = \"uuid-0.8.2\",\n build_file = Label(\"@crates//crates:BUILD.uuid-0.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__vcpkg-0.2.15\",\n sha256 = \"accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/vcpkg/0.2.15/download\"],\n strip_prefix = \"vcpkg-0.2.15\",\n build_file = Label(\"@crates//crates:BUILD.vcpkg-0.2.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__version_check-0.9.5\",\n sha256 = \"0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/version_check/0.9.5/download\"],\n strip_prefix = \"version_check-0.9.5\",\n build_file = Label(\"@crates//crates:BUILD.version_check-0.9.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__walkdir-2.5.0\",\n sha256 = \"29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/walkdir/2.5.0/download\"],\n strip_prefix = \"walkdir-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.walkdir-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasi-0.11.1-wasi-snapshot-preview1\",\n sha256 = \"ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasi/0.11.1+wasi-snapshot-preview1/download\"],\n strip_prefix = \"wasi-0.11.1+wasi-snapshot-preview1\",\n build_file = Label(\"@crates//crates:BUILD.wasi-0.11.1+wasi-snapshot-preview1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasip2-1.0.3-wasi-0.2.9\",\n sha256 = \"20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasip2/1.0.3+wasi-0.2.9/download\"],\n strip_prefix = \"wasip2-1.0.3+wasi-0.2.9\",\n build_file = Label(\"@crates//crates:BUILD.wasip2-1.0.3+wasi-0.2.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-util-0.1.11\",\n sha256 = \"c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi-util/0.1.11/download\"],\n strip_prefix = \"winapi-util-0.1.11\",\n build_file = Label(\"@crates//crates:BUILD.winapi-util-0.1.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-link-0.2.1\",\n sha256 = \"f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-link/0.2.1/download\"],\n strip_prefix = \"windows-link-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-link-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.48.0\",\n sha256 = \"677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.48.0/download\"],\n strip_prefix = \"windows-sys-0.48.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.48.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.61.2\",\n sha256 = \"ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.61.2/download\"],\n strip_prefix = \"windows-sys-0.61.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.61.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-targets-0.48.5\",\n sha256 = \"9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-targets/0.48.5/download\"],\n strip_prefix = \"windows-targets-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows-targets-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_gnullvm-0.48.5\",\n sha256 = \"2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_gnullvm/0.48.5/download\"],\n strip_prefix = \"windows_aarch64_gnullvm-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_gnullvm-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_msvc-0.48.5\",\n sha256 = \"dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_msvc/0.48.5/download\"],\n strip_prefix = \"windows_aarch64_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnu-0.48.5\",\n sha256 = \"a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnu/0.48.5/download\"],\n strip_prefix = \"windows_i686_gnu-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnu-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_msvc-0.48.5\",\n sha256 = \"8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_msvc/0.48.5/download\"],\n strip_prefix = \"windows_i686_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnu-0.48.5\",\n sha256 = \"53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnu/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_gnu-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnu-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnullvm-0.48.5\",\n sha256 = \"0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnullvm/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_gnullvm-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnullvm-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_msvc-0.48.5\",\n sha256 = \"ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_msvc/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winnow-0.6.26\",\n sha256 = \"1e90edd2ac1aa278a5c4599b1d89cf03074b610800f866d4026dc199d7929a28\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winnow/0.6.26/download\"],\n strip_prefix = \"winnow-0.6.26\",\n build_file = Label(\"@crates//crates:BUILD.winnow-0.6.26.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wit-bindgen-0.57.1\",\n sha256 = \"1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wit-bindgen/0.57.1/download\"],\n strip_prefix = \"wit-bindgen-0.57.1\",\n build_file = Label(\"@crates//crates:BUILD.wit-bindgen-0.57.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__write16-1.0.0\",\n sha256 = \"d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/write16/1.0.0/download\"],\n strip_prefix = \"write16-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.write16-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__writeable-0.5.5\",\n sha256 = \"1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/writeable/0.5.5/download\"],\n strip_prefix = \"writeable-0.5.5\",\n build_file = Label(\"@crates//crates:BUILD.writeable-0.5.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yoke-0.7.5\",\n sha256 = \"120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yoke/0.7.5/download\"],\n strip_prefix = \"yoke-0.7.5\",\n build_file = Label(\"@crates//crates:BUILD.yoke-0.7.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yoke-derive-0.7.5\",\n sha256 = \"2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yoke-derive/0.7.5/download\"],\n strip_prefix = \"yoke-derive-0.7.5\",\n build_file = Label(\"@crates//crates:BUILD.yoke-derive-0.7.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerofrom-0.1.8\",\n sha256 = \"0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerofrom/0.1.8/download\"],\n strip_prefix = \"zerofrom-0.1.8\",\n build_file = Label(\"@crates//crates:BUILD.zerofrom-0.1.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerofrom-derive-0.1.7\",\n sha256 = \"11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerofrom-derive/0.1.7/download\"],\n strip_prefix = \"zerofrom-derive-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.zerofrom-derive-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zeroize-1.8.2\",\n sha256 = \"b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zeroize/1.8.2/download\"],\n strip_prefix = \"zeroize-1.8.2\",\n build_file = Label(\"@crates//crates:BUILD.zeroize-1.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zeroize_derive-1.4.3\",\n sha256 = \"85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zeroize_derive/1.4.3/download\"],\n strip_prefix = \"zeroize_derive-1.4.3\",\n build_file = Label(\"@crates//crates:BUILD.zeroize_derive-1.4.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerovec-0.10.4\",\n sha256 = \"aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerovec/0.10.4/download\"],\n strip_prefix = \"zerovec-0.10.4\",\n build_file = Label(\"@crates//crates:BUILD.zerovec-0.10.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerovec-derive-0.10.3\",\n sha256 = \"6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerovec-derive/0.10.3/download\"],\n strip_prefix = \"zerovec-derive-0.10.3\",\n build_file = Label(\"@crates//crates:BUILD.zerovec-derive-0.10.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zmij-1.0.21\",\n sha256 = \"b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zmij/1.0.21/download\"],\n strip_prefix = \"zmij-1.0.21\",\n build_file = Label(\"@crates//crates:BUILD.zmij-1.0.21.bazel\"),\n )\n\n return [\n struct(repo=\"crates__argon2-0.5.3\", is_dev_dep = False),\n struct(repo=\"crates__dirs-5.0.1\", is_dev_dep = False),\n struct(repo=\"crates__libc-0.2.186\", is_dev_dep = False),\n struct(repo=\"crates__once_cell-1.21.4\", is_dev_dep = False),\n struct(repo=\"crates__openssl-0.10.80\", is_dev_dep = False),\n struct(repo=\"crates__parking_lot-0.12.5\", is_dev_dep = False),\n struct(repo=\"crates__parsec-client-0.16.0\", is_dev_dep = False),\n struct(repo=\"crates__serde-1.0.228\", is_dev_dep = False),\n struct(repo=\"crates__serde_json-1.0.150\", is_dev_dep = False),\n struct(repo=\"crates__tempfile-3.27.0\", is_dev_dep = False),\n struct(repo=\"crates__toml-0.8.19\", is_dev_dep = False),\n struct(repo=\"crates__zeroize-1.8.2\", is_dev_dep = False),\n struct(repo = \"crates__serial_test-3.5.0\", is_dev_dep = True),\n ]\n" + "defs.bzl": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\"\"\"\n# `crates_repository` API\n\n- [aliases](#aliases)\n- [crate_deps](#crate_deps)\n- [all_crate_deps](#all_crate_deps)\n- [crate_repositories](#crate_repositories)\n\n\"\"\"\n\nload(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"new_git_repository\")\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\nload(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")\nload(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\nload(\"@rules_rust//crate_universe/private:local_crate_mirror.bzl\", \"local_crate_mirror\")\n\n###############################################################################\n# MACROS API\n###############################################################################\n\n# An identifier that represent common dependencies (unconditional).\n_COMMON_CONDITION = \"\"\n\ndef _flatten_dependency_maps(all_dependency_maps):\n \"\"\"Flatten a list of dependency maps into one dictionary.\n\n Dependency maps have the following structure:\n\n ```python\n DEPENDENCIES_MAP = {\n # The first key in the map is a Bazel package\n # name of the workspace this file is defined in.\n \"workspace_member_package\": {\n\n # Not all dependencies are supported for all platforms.\n # the condition key is the condition required to be true\n # on the host platform.\n \"condition\": {\n\n # An alias to a crate target. # The label of the crate target the\n # Aliases are only crate names. # package name refers to.\n \"package_name\": \"@full//:label\",\n }\n }\n }\n ```\n\n Args:\n all_dependency_maps (list): A list of dicts as described above\n\n Returns:\n dict: A dictionary as described above\n \"\"\"\n dependencies = {}\n\n for workspace_deps_map in all_dependency_maps:\n for pkg_name, conditional_deps_map in workspace_deps_map.items():\n if pkg_name not in dependencies:\n non_frozen_map = dict()\n for key, values in conditional_deps_map.items():\n non_frozen_map.update({key: dict(values.items())})\n dependencies.setdefault(pkg_name, non_frozen_map)\n continue\n\n for condition, deps_map in conditional_deps_map.items():\n # If the condition has not been recorded, do so and continue\n if condition not in dependencies[pkg_name]:\n dependencies[pkg_name].setdefault(condition, dict(deps_map.items()))\n continue\n\n # Alert on any miss-matched dependencies\n inconsistent_entries = []\n for crate_name, crate_label in deps_map.items():\n existing = dependencies[pkg_name][condition].get(crate_name)\n if existing and existing != crate_label:\n inconsistent_entries.append((crate_name, existing, crate_label))\n dependencies[pkg_name][condition].update({crate_name: crate_label})\n\n return dependencies\n\ndef crate_deps(deps, package_name = None):\n \"\"\"Finds the fully qualified label of the requested crates for the package where this macro is called.\n\n Args:\n deps (list): The desired list of crate targets.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()`.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if not deps:\n return []\n\n if package_name == None:\n package_name = native.package_name()\n\n # Join both sets of dependencies\n dependencies = _flatten_dependency_maps([\n _NORMAL_DEPENDENCIES,\n _NORMAL_DEV_DEPENDENCIES,\n _PROC_MACRO_DEPENDENCIES,\n _PROC_MACRO_DEV_DEPENDENCIES,\n _BUILD_DEPENDENCIES,\n _BUILD_PROC_MACRO_DEPENDENCIES,\n ]).pop(package_name, {})\n\n # Combine all conditional packages so we can easily index over a flat list\n # TODO: Perhaps this should actually return select statements and maintain\n # the conditionals of the dependencies\n flat_deps = {}\n for deps_set in dependencies.values():\n for crate_name, crate_label in deps_set.items():\n flat_deps.update({crate_name: crate_label})\n\n missing_crates = []\n crate_targets = []\n for crate_target in deps:\n if crate_target not in flat_deps:\n missing_crates.append(crate_target)\n else:\n crate_targets.append(flat_deps[crate_target])\n\n if missing_crates:\n fail(\"Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`\".format(\n missing_crates,\n package_name,\n dependencies,\n ))\n\n return crate_targets\n\ndef all_crate_deps(\n normal = False, \n normal_dev = False, \n proc_macro = False, \n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Finds the fully qualified label of all requested direct crate dependencies \\\n for the package where this macro is called.\n\n If no parameters are set, all normal dependencies are returned. Setting any one flag will\n otherwise impact the contents of the returned list.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list.\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_dependency_maps = []\n if normal:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n if normal_dev:\n all_dependency_maps.append(_NORMAL_DEV_DEPENDENCIES)\n if proc_macro:\n all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES)\n if proc_macro_dev:\n all_dependency_maps.append(_PROC_MACRO_DEV_DEPENDENCIES)\n if build:\n all_dependency_maps.append(_BUILD_DEPENDENCIES)\n if build_proc_macro:\n all_dependency_maps.append(_BUILD_PROC_MACRO_DEPENDENCIES)\n\n # Default to always using normal dependencies\n if not all_dependency_maps:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n\n dependencies = _flatten_dependency_maps(all_dependency_maps).pop(package_name, None)\n\n if not dependencies:\n if dependencies == None:\n fail(\"Tried to get all_crate_deps for package \" + package_name + \" but that package had no Cargo.toml file\")\n else:\n return []\n\n crate_deps = list(dependencies.pop(_COMMON_CONDITION, {}).values())\n for condition, deps in dependencies.items():\n crate_deps += selects.with_or({\n tuple(_CONDITIONS[condition]): deps.values(),\n \"//conditions:default\": [],\n })\n\n return crate_deps\n\ndef aliases(\n normal = False,\n normal_dev = False,\n proc_macro = False,\n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Produces a map of Crate alias names to their original label\n\n If no dependency kinds are specified, `normal` and `proc_macro` are used by default.\n Setting any one flag will otherwise determine the contents of the returned dict.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list..\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n dict: The aliases of all associated packages\n \"\"\"\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_aliases_maps = []\n if normal:\n all_aliases_maps.append(_NORMAL_ALIASES)\n if normal_dev:\n all_aliases_maps.append(_NORMAL_DEV_ALIASES)\n if proc_macro:\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n if proc_macro_dev:\n all_aliases_maps.append(_PROC_MACRO_DEV_ALIASES)\n if build:\n all_aliases_maps.append(_BUILD_ALIASES)\n if build_proc_macro:\n all_aliases_maps.append(_BUILD_PROC_MACRO_ALIASES)\n\n # Default to always using normal aliases\n if not all_aliases_maps:\n all_aliases_maps.append(_NORMAL_ALIASES)\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n\n aliases = _flatten_dependency_maps(all_aliases_maps).pop(package_name, None)\n\n if not aliases:\n return dict()\n\n common_items = aliases.pop(_COMMON_CONDITION, {}).items()\n\n # If there are only common items in the dictionary, immediately return them\n if not len(aliases.keys()) == 1:\n return dict(common_items)\n\n # Build a single select statement where each conditional has accounted for the\n # common set of aliases.\n crate_aliases = {\"//conditions:default\": dict(common_items)}\n for condition, deps in aliases.items():\n condition_triples = _CONDITIONS[condition]\n for triple in condition_triples:\n if triple in crate_aliases:\n crate_aliases[triple].update(deps)\n else:\n crate_aliases.update({triple: dict(deps.items() + common_items)})\n\n return select(crate_aliases)\n\n###############################################################################\n# WORKSPACE MEMBER DEPS AND ALIASES\n###############################################################################\n\n_NORMAL_DEPENDENCIES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n \"argon2\": Label(\"@crates//:argon2-0.5.3\"),\n \"dirs\": Label(\"@crates//:dirs-5.0.1\"),\n \"libc\": Label(\"@crates//:libc-0.2.186\"),\n \"once_cell\": Label(\"@crates//:once_cell-1.21.4\"),\n \"openssl\": Label(\"@crates//:openssl-0.10.68\"),\n \"parking_lot\": Label(\"@crates//:parking_lot-0.12.5\"),\n \"parsec-client\": Label(\"@crates//:parsec-client-0.16.0\"),\n \"serde\": Label(\"@crates//:serde-1.0.228\"),\n \"serde_json\": Label(\"@crates//:serde_json-1.0.150\"),\n \"tempfile\": Label(\"@crates//:tempfile-3.27.0\"),\n \"toml\": Label(\"@crates//:toml-0.8.19\"),\n \"zeroize\": Label(\"@crates//:zeroize-1.8.2\"),\n },\n },\n}\n\n\n_NORMAL_ALIASES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_NORMAL_DEV_DEPENDENCIES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n \"serial_test\": Label(\"@crates//:serial_test-3.5.0\"),\n },\n },\n}\n\n\n_NORMAL_DEV_ALIASES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_PROC_MACRO_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_PROC_MACRO_ALIASES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_PROC_MACRO_DEV_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_PROC_MACRO_DEV_ALIASES = {\n \"score/cryptoki\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_BUILD_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_BUILD_ALIASES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_DEPENDENCIES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_ALIASES = {\n \"score/cryptoki\": {\n },\n}\n\n\n_CONDITIONS = {\n \"aarch64-linux-android\": [],\n \"aarch64-pc-windows-gnullvm\": [],\n \"aarch64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\"],\n \"aarch64-unknown-nto-qnx800\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\"],\n \"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [],\n \"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), not(any(all(target_os = \\\"linux\\\", target_env = \\\"\\\"), getrandom_backend = \\\"custom\\\", getrandom_backend = \\\"linux_raw\\\", getrandom_backend = \\\"rdrand\\\", getrandom_backend = \\\"rndr\\\"))))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\"],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_os = \\\"linux\\\"))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\"],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_vendor = \\\"apple\\\"))\": [],\n \"cfg(all(target_arch = \\\"loongarch64\\\", target_os = \\\"linux\\\"))\": [],\n \"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"wasi\\\", target_env = \\\"p2\\\"))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"gnu\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86_64\\\", target_env = \\\"gnu\\\", not(target_abi = \\\"llvm\\\"), not(windows_raw_dylib)))\": [\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(all(target_arch = \\\"x86_64\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_os = \\\"uefi\\\", getrandom_backend = \\\"efi_rng\\\"))\": [],\n \"cfg(any())\": [],\n \"cfg(any(target_arch = \\\"x86\\\", target_arch = \\\"x86_64\\\"))\": [\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(any(target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"hurd\\\", target_os = \\\"illumos\\\", target_os = \\\"cygwin\\\", all(target_os = \\\"horizon\\\", target_arch = \\\"arm\\\")))\": [],\n \"cfg(any(target_os = \\\"haiku\\\", target_os = \\\"redox\\\", target_os = \\\"nto\\\", target_os = \\\"aix\\\"))\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\"],\n \"cfg(any(target_os = \\\"ios\\\", target_os = \\\"visionos\\\", target_os = \\\"watchos\\\", target_os = \\\"tvos\\\"))\": [],\n \"cfg(any(target_os = \\\"macos\\\", target_os = \\\"openbsd\\\", target_os = \\\"vita\\\", target_os = \\\"emscripten\\\"))\": [],\n \"cfg(any(unix, target_os = \\\"wasi\\\"))\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(target_os = \\\"hermit\\\")\": [],\n \"cfg(target_os = \\\"netbsd\\\")\": [],\n \"cfg(target_os = \\\"redox\\\")\": [],\n \"cfg(target_os = \\\"solaris\\\")\": [],\n \"cfg(target_os = \\\"vxworks\\\")\": [],\n \"cfg(target_os = \\\"wasi\\\")\": [],\n \"cfg(unix)\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"cfg(windows)\": [],\n \"x86_64-pc-nto-qnx800\": [\"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\"],\n \"x86_64-pc-windows-gnullvm\": [],\n \"x86_64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n}\n\n###############################################################################\n\ndef crate_repositories():\n \"\"\"A macro for defining repositories for all generated crates.\n\n Returns:\n A list of repos visible to the module through the module extension.\n \"\"\"\n maybe(\n http_archive,\n name = \"crates__aho-corasick-1.1.4\",\n sha256 = \"ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aho-corasick/1.1.4/download\"],\n strip_prefix = \"aho-corasick-1.1.4\",\n build_file = Label(\"@crates//crates:BUILD.aho-corasick-1.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anyhow-1.0.102\",\n sha256 = \"7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anyhow/1.0.102/download\"],\n strip_prefix = \"anyhow-1.0.102\",\n build_file = Label(\"@crates//crates:BUILD.anyhow-1.0.102.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__argon2-0.5.3\",\n sha256 = \"3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/argon2/0.5.3/download\"],\n strip_prefix = \"argon2-0.5.3\",\n build_file = Label(\"@crates//crates:BUILD.argon2-0.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__autocfg-1.5.1\",\n sha256 = \"f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/autocfg/1.5.1/download\"],\n strip_prefix = \"autocfg-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.autocfg-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__base64ct-1.6.0\",\n sha256 = \"8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/base64ct/1.6.0/download\"],\n strip_prefix = \"base64ct-1.6.0\",\n build_file = Label(\"@crates//crates:BUILD.base64ct-1.6.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bincode-1.3.3\",\n sha256 = \"b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bincode/1.3.3/download\"],\n strip_prefix = \"bincode-1.3.3\",\n build_file = Label(\"@crates//crates:BUILD.bincode-1.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bitflags-2.11.1\",\n sha256 = \"c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bitflags/2.11.1/download\"],\n strip_prefix = \"bitflags-2.11.1\",\n build_file = Label(\"@crates//crates:BUILD.bitflags-2.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__blake2-0.10.6\",\n sha256 = \"46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/blake2/0.10.6/download\"],\n strip_prefix = \"blake2-0.10.6\",\n build_file = Label(\"@crates//crates:BUILD.blake2-0.10.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__block-buffer-0.10.4\",\n sha256 = \"3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/block-buffer/0.10.4/download\"],\n strip_prefix = \"block-buffer-0.10.4\",\n build_file = Label(\"@crates//crates:BUILD.block-buffer-0.10.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytes-1.11.1\",\n sha256 = \"1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytes/1.11.1/download\"],\n strip_prefix = \"bytes-1.11.1\",\n build_file = Label(\"@crates//crates:BUILD.bytes-1.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cc-1.2.63\",\n sha256 = \"556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cc/1.2.63/download\"],\n strip_prefix = \"cc-1.2.63\",\n build_file = Label(\"@crates//crates:BUILD.cc-1.2.63.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg-if-1.0.4\",\n sha256 = \"9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg-if/1.0.4/download\"],\n strip_prefix = \"cfg-if-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.cfg-if-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cmake-0.1.58\",\n sha256 = \"c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cmake/0.1.58/download\"],\n strip_prefix = \"cmake-0.1.58\",\n build_file = Label(\"@crates//crates:BUILD.cmake-0.1.58.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cpufeatures-0.2.17\",\n sha256 = \"59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cpufeatures/0.2.17/download\"],\n strip_prefix = \"cpufeatures-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.cpufeatures-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crypto-common-0.1.7\",\n sha256 = \"78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crypto-common/0.1.7/download\"],\n strip_prefix = \"crypto-common-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.crypto-common-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__derivative-2.2.0\",\n sha256 = \"fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/derivative/2.2.0/download\"],\n strip_prefix = \"derivative-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.derivative-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__digest-0.10.7\",\n sha256 = \"9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/digest/0.10.7/download\"],\n strip_prefix = \"digest-0.10.7\",\n build_file = Label(\"@crates//crates:BUILD.digest-0.10.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dirs-5.0.1\",\n sha256 = \"44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dirs/5.0.1/download\"],\n strip_prefix = \"dirs-5.0.1\",\n build_file = Label(\"@crates//crates:BUILD.dirs-5.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dirs-sys-0.4.1\",\n sha256 = \"520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dirs-sys/0.4.1/download\"],\n strip_prefix = \"dirs-sys-0.4.1\",\n build_file = Label(\"@crates//crates:BUILD.dirs-sys-0.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__displaydoc-0.2.6\",\n sha256 = \"1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/displaydoc/0.2.6/download\"],\n strip_prefix = \"displaydoc-0.2.6\",\n build_file = Label(\"@crates//crates:BUILD.displaydoc-0.2.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__either-1.16.0\",\n sha256 = \"91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/either/1.16.0/download\"],\n strip_prefix = \"either-1.16.0\",\n build_file = Label(\"@crates//crates:BUILD.either-1.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__equivalent-1.0.2\",\n sha256 = \"877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/equivalent/1.0.2/download\"],\n strip_prefix = \"equivalent-1.0.2\",\n build_file = Label(\"@crates//crates:BUILD.equivalent-1.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__errno-0.3.14\",\n sha256 = \"39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/errno/0.3.14/download\"],\n strip_prefix = \"errno-0.3.14\",\n build_file = Label(\"@crates//crates:BUILD.errno-0.3.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fastrand-2.4.1\",\n sha256 = \"9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fastrand/2.4.1/download\"],\n strip_prefix = \"fastrand-2.4.1\",\n build_file = Label(\"@crates//crates:BUILD.fastrand-2.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__find-msvc-tools-0.1.9\",\n sha256 = \"5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/find-msvc-tools/0.1.9/download\"],\n strip_prefix = \"find-msvc-tools-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.find-msvc-tools-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-0.3.2\",\n sha256 = \"f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types/0.3.2/download\"],\n strip_prefix = \"foreign-types-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-shared-0.1.1\",\n sha256 = \"00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types-shared/0.1.1/download\"],\n strip_prefix = \"foreign-types-shared-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-shared-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__form_urlencoded-1.2.2\",\n sha256 = \"cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/form_urlencoded/1.2.2/download\"],\n strip_prefix = \"form_urlencoded-1.2.2\",\n build_file = Label(\"@crates//crates:BUILD.form_urlencoded-1.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-core-0.3.32\",\n sha256 = \"7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-core/0.3.32/download\"],\n strip_prefix = \"futures-core-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-core-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-executor-0.3.32\",\n sha256 = \"baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-executor/0.3.32/download\"],\n strip_prefix = \"futures-executor-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-executor-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-task-0.3.32\",\n sha256 = \"037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-task/0.3.32/download\"],\n strip_prefix = \"futures-task-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-task-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-util-0.3.32\",\n sha256 = \"389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-util/0.3.32/download\"],\n strip_prefix = \"futures-util-0.3.32\",\n build_file = Label(\"@crates//crates:BUILD.futures-util-0.3.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__generic-array-0.14.7\",\n sha256 = \"85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/generic-array/0.14.7/download\"],\n strip_prefix = \"generic-array-0.14.7\",\n build_file = Label(\"@crates//crates:BUILD.generic-array-0.14.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.2.17\",\n sha256 = \"ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.2.17/download\"],\n strip_prefix = \"getrandom-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.3.4\",\n sha256 = \"899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.3.4/download\"],\n strip_prefix = \"getrandom-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.14.5\",\n sha256 = \"e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.14.5/download\"],\n strip_prefix = \"hashbrown-0.14.5\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.14.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_collections-1.5.0\",\n sha256 = \"db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_collections/1.5.0/download\"],\n strip_prefix = \"icu_collections-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_collections-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locid-1.5.0\",\n sha256 = \"13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locid/1.5.0/download\"],\n strip_prefix = \"icu_locid-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locid-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locid_transform-1.5.0\",\n sha256 = \"01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locid_transform/1.5.0/download\"],\n strip_prefix = \"icu_locid_transform-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locid_transform-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locid_transform_data-1.5.1\",\n sha256 = \"7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locid_transform_data/1.5.1/download\"],\n strip_prefix = \"icu_locid_transform_data-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_locid_transform_data-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_normalizer-1.5.0\",\n sha256 = \"19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_normalizer/1.5.0/download\"],\n strip_prefix = \"icu_normalizer-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_normalizer-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_normalizer_data-1.5.1\",\n sha256 = \"c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_normalizer_data/1.5.1/download\"],\n strip_prefix = \"icu_normalizer_data-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_normalizer_data-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_properties-1.5.1\",\n sha256 = \"93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_properties/1.5.1/download\"],\n strip_prefix = \"icu_properties-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_properties-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_properties_data-1.5.1\",\n sha256 = \"85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_properties_data/1.5.1/download\"],\n strip_prefix = \"icu_properties_data-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_properties_data-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_provider-1.5.0\",\n sha256 = \"6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_provider/1.5.0/download\"],\n strip_prefix = \"icu_provider-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_provider-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_provider_macros-1.5.0\",\n sha256 = \"1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_provider_macros/1.5.0/download\"],\n strip_prefix = \"icu_provider_macros-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_provider_macros-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__idna-1.0.3\",\n sha256 = \"686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/idna/1.0.3/download\"],\n strip_prefix = \"idna-1.0.3\",\n build_file = Label(\"@crates//crates:BUILD.idna-1.0.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__idna_adapter-1.2.0\",\n sha256 = \"daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/idna_adapter/1.2.0/download\"],\n strip_prefix = \"idna_adapter-1.2.0\",\n build_file = Label(\"@crates//crates:BUILD.idna_adapter-1.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__indexmap-2.0.0\",\n sha256 = \"d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/indexmap/2.0.0/download\"],\n strip_prefix = \"indexmap-2.0.0\",\n build_file = Label(\"@crates//crates:BUILD.indexmap-2.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itertools-0.10.5\",\n sha256 = \"b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itertools/0.10.5/download\"],\n strip_prefix = \"itertools-0.10.5\",\n build_file = Label(\"@crates//crates:BUILD.itertools-0.10.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itoa-1.0.18\",\n sha256 = \"8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itoa/1.0.18/download\"],\n strip_prefix = \"itoa-1.0.18\",\n build_file = Label(\"@crates//crates:BUILD.itoa-1.0.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libc-0.2.186\",\n sha256 = \"68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libc/0.2.186/download\"],\n strip_prefix = \"libc-0.2.186\",\n build_file = Label(\"@crates//crates:BUILD.libc-0.2.186.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libredox-0.1.17\",\n sha256 = \"f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libredox/0.1.17/download\"],\n strip_prefix = \"libredox-0.1.17\",\n build_file = Label(\"@crates//crates:BUILD.libredox-0.1.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__linux-raw-sys-0.12.1\",\n sha256 = \"32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/linux-raw-sys/0.12.1/download\"],\n strip_prefix = \"linux-raw-sys-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.linux-raw-sys-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__litemap-0.7.5\",\n sha256 = \"23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/litemap/0.7.5/download\"],\n strip_prefix = \"litemap-0.7.5\",\n build_file = Label(\"@crates//crates:BUILD.litemap-0.7.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__lock_api-0.4.14\",\n sha256 = \"224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/lock_api/0.4.14/download\"],\n strip_prefix = \"lock_api-0.4.14\",\n build_file = Label(\"@crates//crates:BUILD.lock_api-0.4.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__log-0.4.30\",\n sha256 = \"616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/log/0.4.30/download\"],\n strip_prefix = \"log-0.4.30\",\n build_file = Label(\"@crates//crates:BUILD.log-0.4.30.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memchr-2.8.1\",\n sha256 = \"6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memchr/2.8.1/download\"],\n strip_prefix = \"memchr-2.8.1\",\n build_file = Label(\"@crates//crates:BUILD.memchr-2.8.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-0.4.3\",\n sha256 = \"35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num/0.4.3/download\"],\n strip_prefix = \"num-0.4.3\",\n build_file = Label(\"@crates//crates:BUILD.num-0.4.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-bigint-0.4.6\",\n sha256 = \"a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-bigint/0.4.6/download\"],\n strip_prefix = \"num-bigint-0.4.6\",\n build_file = Label(\"@crates//crates:BUILD.num-bigint-0.4.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-complex-0.4.6\",\n sha256 = \"73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-complex/0.4.6/download\"],\n strip_prefix = \"num-complex-0.4.6\",\n build_file = Label(\"@crates//crates:BUILD.num-complex-0.4.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-derive-0.4.2\",\n sha256 = \"ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-derive/0.4.2/download\"],\n strip_prefix = \"num-derive-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.num-derive-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-integer-0.1.46\",\n sha256 = \"7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-integer/0.1.46/download\"],\n strip_prefix = \"num-integer-0.1.46\",\n build_file = Label(\"@crates//crates:BUILD.num-integer-0.1.46.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-iter-0.1.45\",\n sha256 = \"1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-iter/0.1.45/download\"],\n strip_prefix = \"num-iter-0.1.45\",\n build_file = Label(\"@crates//crates:BUILD.num-iter-0.1.45.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-rational-0.4.2\",\n sha256 = \"f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-rational/0.4.2/download\"],\n strip_prefix = \"num-rational-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.num-rational-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-traits-0.2.19\",\n sha256 = \"071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-traits/0.2.19/download\"],\n strip_prefix = \"num-traits-0.2.19\",\n build_file = Label(\"@crates//crates:BUILD.num-traits-0.2.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__once_cell-1.21.4\",\n sha256 = \"9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/once_cell/1.21.4/download\"],\n strip_prefix = \"once_cell-1.21.4\",\n build_file = Label(\"@crates//crates:BUILD.once_cell-1.21.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__openssl-0.10.68\",\n sha256 = \"6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/openssl/0.10.68/download\"],\n strip_prefix = \"openssl-0.10.68\",\n build_file = Label(\"@crates//crates:BUILD.openssl-0.10.68.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__openssl-macros-0.1.1\",\n sha256 = \"a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/openssl-macros/0.1.1/download\"],\n strip_prefix = \"openssl-macros-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.openssl-macros-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__openssl-sys-0.9.116\",\n patch_args = [\n \"-p1\",\n ],\n patches = [\n \"@@//third_party/patches:openssl_sys_build_rs.patch\",\n ],\n sha256 = \"f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/openssl-sys/0.9.116/download\"],\n strip_prefix = \"openssl-sys-0.9.116\",\n build_file = Label(\"@crates//crates:BUILD.openssl-sys-0.9.116.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__option-ext-0.2.0\",\n sha256 = \"04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/option-ext/0.2.0/download\"],\n strip_prefix = \"option-ext-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.option-ext-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking_lot-0.12.5\",\n sha256 = \"93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking_lot/0.12.5/download\"],\n strip_prefix = \"parking_lot-0.12.5\",\n build_file = Label(\"@crates//crates:BUILD.parking_lot-0.12.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking_lot_core-0.9.12\",\n sha256 = \"2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking_lot_core/0.9.12/download\"],\n strip_prefix = \"parking_lot_core-0.9.12\",\n build_file = Label(\"@crates//crates:BUILD.parking_lot_core-0.9.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parsec-client-0.16.0\",\n sha256 = \"a36f9d8e27166cf0586913812454174286e094d594cc8b28d8a8d02d64406bbc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parsec-client/0.16.0/download\"],\n strip_prefix = \"parsec-client-0.16.0\",\n build_file = Label(\"@crates//crates:BUILD.parsec-client-0.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parsec-interface-0.29.1\",\n sha256 = \"cc706e09209b30f10baa35709d41b9cc01d4931b21c00679f59db96cd1650add\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parsec-interface/0.29.1/download\"],\n strip_prefix = \"parsec-interface-0.29.1\",\n build_file = Label(\"@crates//crates:BUILD.parsec-interface-0.29.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__password-hash-0.5.0\",\n sha256 = \"346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/password-hash/0.5.0/download\"],\n strip_prefix = \"password-hash-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.password-hash-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__percent-encoding-2.3.2\",\n sha256 = \"9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/percent-encoding/2.3.2/download\"],\n strip_prefix = \"percent-encoding-2.3.2\",\n build_file = Label(\"@crates//crates:BUILD.percent-encoding-2.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pin-project-lite-0.2.17\",\n sha256 = \"a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pin-project-lite/0.2.17/download\"],\n strip_prefix = \"pin-project-lite-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.pin-project-lite-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pkg-config-0.3.33\",\n sha256 = \"19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pkg-config/0.3.33/download\"],\n strip_prefix = \"pkg-config-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.pkg-config-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__proc-macro2-1.0.106\",\n sha256 = \"8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/proc-macro2/1.0.106/download\"],\n strip_prefix = \"proc-macro2-1.0.106\",\n build_file = Label(\"@crates//crates:BUILD.proc-macro2-1.0.106.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__prost-0.9.0\",\n sha256 = \"444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/prost/0.9.0/download\"],\n strip_prefix = \"prost-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.prost-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__prost-derive-0.9.0\",\n sha256 = \"f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/prost-derive/0.9.0/download\"],\n strip_prefix = \"prost-derive-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.prost-derive-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__psa-crypto-0.12.0\",\n sha256 = \"89c2256e525b9a45ec3bbb3382a43dd8809240279e0aab8ea7ee220e9295445b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/psa-crypto/0.12.0/download\"],\n strip_prefix = \"psa-crypto-0.12.0\",\n build_file = Label(\"@crates//crates:BUILD.psa-crypto-0.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__psa-crypto-sys-0.12.0\",\n sha256 = \"f170cac3a328e1678916b276067ec170a5a51db1b9b8b4c00b44c2839819a963\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/psa-crypto-sys/0.12.0/download\"],\n strip_prefix = \"psa-crypto-sys-0.12.0\",\n build_file = Label(\"@crates//crates:BUILD.psa-crypto-sys-0.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quote-1.0.45\",\n sha256 = \"41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quote/1.0.45/download\"],\n strip_prefix = \"quote-1.0.45\",\n build_file = Label(\"@crates//crates:BUILD.quote-1.0.45.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__r-efi-5.3.0\",\n sha256 = \"69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/r-efi/5.3.0/download\"],\n strip_prefix = \"r-efi-5.3.0\",\n build_file = Label(\"@crates//crates:BUILD.r-efi-5.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_core-0.6.4\",\n sha256 = \"ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_core/0.6.4/download\"],\n strip_prefix = \"rand_core-0.6.4\",\n build_file = Label(\"@crates//crates:BUILD.rand_core-0.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__redox_syscall-0.5.18\",\n sha256 = \"ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/redox_syscall/0.5.18/download\"],\n strip_prefix = \"redox_syscall-0.5.18\",\n build_file = Label(\"@crates//crates:BUILD.redox_syscall-0.5.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__redox_users-0.4.6\",\n sha256 = \"ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/redox_users/0.4.6/download\"],\n strip_prefix = \"redox_users-0.4.6\",\n build_file = Label(\"@crates//crates:BUILD.redox_users-0.4.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-1.12.3\",\n sha256 = \"e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex/1.12.3/download\"],\n strip_prefix = \"regex-1.12.3\",\n build_file = Label(\"@crates//crates:BUILD.regex-1.12.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-automata-0.4.14\",\n sha256 = \"6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-automata/0.4.14/download\"],\n strip_prefix = \"regex-automata-0.4.14\",\n build_file = Label(\"@crates//crates:BUILD.regex-automata-0.4.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-syntax-0.8.10\",\n sha256 = \"dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-syntax/0.8.10/download\"],\n strip_prefix = \"regex-syntax-0.8.10\",\n build_file = Label(\"@crates//crates:BUILD.regex-syntax-0.8.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustix-1.1.4\",\n sha256 = \"b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustix/1.1.4/download\"],\n strip_prefix = \"rustix-1.1.4\",\n build_file = Label(\"@crates//crates:BUILD.rustix-1.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__same-file-1.0.6\",\n sha256 = \"93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/same-file/1.0.6/download\"],\n strip_prefix = \"same-file-1.0.6\",\n build_file = Label(\"@crates//crates:BUILD.same-file-1.0.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__scopeguard-1.2.0\",\n sha256 = \"94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/scopeguard/1.2.0/download\"],\n strip_prefix = \"scopeguard-1.2.0\",\n build_file = Label(\"@crates//crates:BUILD.scopeguard-1.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__secrecy-0.8.0\",\n sha256 = \"9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/secrecy/0.8.0/download\"],\n strip_prefix = \"secrecy-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.secrecy-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde-1.0.228\",\n sha256 = \"9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde/1.0.228/download\"],\n strip_prefix = \"serde-1.0.228\",\n build_file = Label(\"@crates//crates:BUILD.serde-1.0.228.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_core-1.0.228\",\n sha256 = \"41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_core/1.0.228/download\"],\n strip_prefix = \"serde_core-1.0.228\",\n build_file = Label(\"@crates//crates:BUILD.serde_core-1.0.228.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_derive-1.0.228\",\n sha256 = \"d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_derive/1.0.228/download\"],\n strip_prefix = \"serde_derive-1.0.228\",\n build_file = Label(\"@crates//crates:BUILD.serde_derive-1.0.228.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_json-1.0.150\",\n sha256 = \"e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_json/1.0.150/download\"],\n strip_prefix = \"serde_json-1.0.150\",\n build_file = Label(\"@crates//crates:BUILD.serde_json-1.0.150.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_spanned-0.6.9\",\n sha256 = \"bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_spanned/0.6.9/download\"],\n strip_prefix = \"serde_spanned-0.6.9\",\n build_file = Label(\"@crates//crates:BUILD.serde_spanned-0.6.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serial_test-3.5.0\",\n sha256 = \"699f4197115b8a7e7ff19c9a315a4bd6fffec26cc4626ef45ecaea389e081c6d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serial_test/3.5.0/download\"],\n strip_prefix = \"serial_test-3.5.0\",\n build_file = Label(\"@crates//crates:BUILD.serial_test-3.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serial_test_derive-3.5.0\",\n sha256 = \"94e153fc76e1c6a068703d6d29c508a0b15c061c4b7e43da59cc097bc342673c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serial_test_derive/3.5.0/download\"],\n strip_prefix = \"serial_test_derive-3.5.0\",\n build_file = Label(\"@crates//crates:BUILD.serial_test_derive-3.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__shlex-2.0.1\",\n sha256 = \"f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/shlex/2.0.1/download\"],\n strip_prefix = \"shlex-2.0.1\",\n build_file = Label(\"@crates//crates:BUILD.shlex-2.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__slab-0.4.12\",\n sha256 = \"0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/slab/0.4.12/download\"],\n strip_prefix = \"slab-0.4.12\",\n build_file = Label(\"@crates//crates:BUILD.slab-0.4.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__smallvec-1.15.1\",\n sha256 = \"67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/smallvec/1.15.1/download\"],\n strip_prefix = \"smallvec-1.15.1\",\n build_file = Label(\"@crates//crates:BUILD.smallvec-1.15.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__stable_deref_trait-1.2.1\",\n sha256 = \"6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/stable_deref_trait/1.2.1/download\"],\n strip_prefix = \"stable_deref_trait-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.stable_deref_trait-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__subtle-2.6.1\",\n sha256 = \"13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/subtle/2.6.1/download\"],\n strip_prefix = \"subtle-2.6.1\",\n build_file = Label(\"@crates//crates:BUILD.subtle-2.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-1.0.109\",\n sha256 = \"72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/1.0.109/download\"],\n strip_prefix = \"syn-1.0.109\",\n build_file = Label(\"@crates//crates:BUILD.syn-1.0.109.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-2.0.117\",\n sha256 = \"e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/2.0.117/download\"],\n strip_prefix = \"syn-2.0.117\",\n build_file = Label(\"@crates//crates:BUILD.syn-2.0.117.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__synstructure-0.13.2\",\n sha256 = \"728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/synstructure/0.13.2/download\"],\n strip_prefix = \"synstructure-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.synstructure-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tempfile-3.27.0\",\n sha256 = \"32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tempfile/3.27.0/download\"],\n strip_prefix = \"tempfile-3.27.0\",\n build_file = Label(\"@crates//crates:BUILD.tempfile-3.27.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-1.0.69\",\n sha256 = \"b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror/1.0.69/download\"],\n strip_prefix = \"thiserror-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-impl-1.0.69\",\n sha256 = \"4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror-impl/1.0.69/download\"],\n strip_prefix = \"thiserror-impl-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-impl-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tinystr-0.7.6\",\n sha256 = \"9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tinystr/0.7.6/download\"],\n strip_prefix = \"tinystr-0.7.6\",\n build_file = Label(\"@crates//crates:BUILD.tinystr-0.7.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml-0.8.19\",\n sha256 = \"a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml/0.8.19/download\"],\n strip_prefix = \"toml-0.8.19\",\n build_file = Label(\"@crates//crates:BUILD.toml-0.8.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_datetime-0.6.11\",\n sha256 = \"22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_datetime/0.6.11/download\"],\n strip_prefix = \"toml_datetime-0.6.11\",\n build_file = Label(\"@crates//crates:BUILD.toml_datetime-0.6.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_edit-0.22.20\",\n sha256 = \"583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_edit/0.22.20/download\"],\n strip_prefix = \"toml_edit-0.22.20\",\n build_file = Label(\"@crates//crates:BUILD.toml_edit-0.22.20.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__typenum-1.20.1\",\n sha256 = \"b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/typenum/1.20.1/download\"],\n strip_prefix = \"typenum-1.20.1\",\n build_file = Label(\"@crates//crates:BUILD.typenum-1.20.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-ident-1.0.24\",\n sha256 = \"e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-ident/1.0.24/download\"],\n strip_prefix = \"unicode-ident-1.0.24\",\n build_file = Label(\"@crates//crates:BUILD.unicode-ident-1.0.24.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__url-2.5.4\",\n sha256 = \"32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/url/2.5.4/download\"],\n strip_prefix = \"url-2.5.4\",\n build_file = Label(\"@crates//crates:BUILD.url-2.5.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf16_iter-1.0.5\",\n sha256 = \"c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf16_iter/1.0.5/download\"],\n strip_prefix = \"utf16_iter-1.0.5\",\n build_file = Label(\"@crates//crates:BUILD.utf16_iter-1.0.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf8_iter-1.0.4\",\n sha256 = \"b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf8_iter/1.0.4/download\"],\n strip_prefix = \"utf8_iter-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.utf8_iter-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uuid-0.8.2\",\n sha256 = \"bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uuid/0.8.2/download\"],\n strip_prefix = \"uuid-0.8.2\",\n build_file = Label(\"@crates//crates:BUILD.uuid-0.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__vcpkg-0.2.15\",\n sha256 = \"accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/vcpkg/0.2.15/download\"],\n strip_prefix = \"vcpkg-0.2.15\",\n build_file = Label(\"@crates//crates:BUILD.vcpkg-0.2.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__version_check-0.9.5\",\n sha256 = \"0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/version_check/0.9.5/download\"],\n strip_prefix = \"version_check-0.9.5\",\n build_file = Label(\"@crates//crates:BUILD.version_check-0.9.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__walkdir-2.5.0\",\n sha256 = \"29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/walkdir/2.5.0/download\"],\n strip_prefix = \"walkdir-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.walkdir-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasi-0.11.1-wasi-snapshot-preview1\",\n sha256 = \"ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasi/0.11.1+wasi-snapshot-preview1/download\"],\n strip_prefix = \"wasi-0.11.1+wasi-snapshot-preview1\",\n build_file = Label(\"@crates//crates:BUILD.wasi-0.11.1+wasi-snapshot-preview1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasip2-1.0.3-wasi-0.2.9\",\n sha256 = \"20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasip2/1.0.3+wasi-0.2.9/download\"],\n strip_prefix = \"wasip2-1.0.3+wasi-0.2.9\",\n build_file = Label(\"@crates//crates:BUILD.wasip2-1.0.3+wasi-0.2.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-util-0.1.11\",\n sha256 = \"c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi-util/0.1.11/download\"],\n strip_prefix = \"winapi-util-0.1.11\",\n build_file = Label(\"@crates//crates:BUILD.winapi-util-0.1.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-link-0.2.1\",\n sha256 = \"f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-link/0.2.1/download\"],\n strip_prefix = \"windows-link-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-link-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.48.0\",\n sha256 = \"677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.48.0/download\"],\n strip_prefix = \"windows-sys-0.48.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.48.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.61.2\",\n sha256 = \"ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.61.2/download\"],\n strip_prefix = \"windows-sys-0.61.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.61.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-targets-0.48.5\",\n sha256 = \"9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-targets/0.48.5/download\"],\n strip_prefix = \"windows-targets-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows-targets-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_gnullvm-0.48.5\",\n sha256 = \"2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_gnullvm/0.48.5/download\"],\n strip_prefix = \"windows_aarch64_gnullvm-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_gnullvm-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_msvc-0.48.5\",\n sha256 = \"dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_msvc/0.48.5/download\"],\n strip_prefix = \"windows_aarch64_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnu-0.48.5\",\n sha256 = \"a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnu/0.48.5/download\"],\n strip_prefix = \"windows_i686_gnu-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnu-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_msvc-0.48.5\",\n sha256 = \"8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_msvc/0.48.5/download\"],\n strip_prefix = \"windows_i686_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnu-0.48.5\",\n sha256 = \"53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnu/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_gnu-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnu-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnullvm-0.48.5\",\n sha256 = \"0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnullvm/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_gnullvm-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnullvm-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_msvc-0.48.5\",\n sha256 = \"ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_msvc/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winnow-0.6.26\",\n sha256 = \"1e90edd2ac1aa278a5c4599b1d89cf03074b610800f866d4026dc199d7929a28\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winnow/0.6.26/download\"],\n strip_prefix = \"winnow-0.6.26\",\n build_file = Label(\"@crates//crates:BUILD.winnow-0.6.26.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wit-bindgen-0.57.1\",\n sha256 = \"1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wit-bindgen/0.57.1/download\"],\n strip_prefix = \"wit-bindgen-0.57.1\",\n build_file = Label(\"@crates//crates:BUILD.wit-bindgen-0.57.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__write16-1.0.0\",\n sha256 = \"d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/write16/1.0.0/download\"],\n strip_prefix = \"write16-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.write16-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__writeable-0.5.5\",\n sha256 = \"1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/writeable/0.5.5/download\"],\n strip_prefix = \"writeable-0.5.5\",\n build_file = Label(\"@crates//crates:BUILD.writeable-0.5.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yoke-0.7.5\",\n sha256 = \"120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yoke/0.7.5/download\"],\n strip_prefix = \"yoke-0.7.5\",\n build_file = Label(\"@crates//crates:BUILD.yoke-0.7.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yoke-derive-0.7.5\",\n sha256 = \"2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yoke-derive/0.7.5/download\"],\n strip_prefix = \"yoke-derive-0.7.5\",\n build_file = Label(\"@crates//crates:BUILD.yoke-derive-0.7.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerofrom-0.1.8\",\n sha256 = \"0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerofrom/0.1.8/download\"],\n strip_prefix = \"zerofrom-0.1.8\",\n build_file = Label(\"@crates//crates:BUILD.zerofrom-0.1.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerofrom-derive-0.1.7\",\n sha256 = \"11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerofrom-derive/0.1.7/download\"],\n strip_prefix = \"zerofrom-derive-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.zerofrom-derive-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zeroize-1.8.2\",\n sha256 = \"b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zeroize/1.8.2/download\"],\n strip_prefix = \"zeroize-1.8.2\",\n build_file = Label(\"@crates//crates:BUILD.zeroize-1.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zeroize_derive-1.4.3\",\n sha256 = \"85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zeroize_derive/1.4.3/download\"],\n strip_prefix = \"zeroize_derive-1.4.3\",\n build_file = Label(\"@crates//crates:BUILD.zeroize_derive-1.4.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerovec-0.10.4\",\n sha256 = \"aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerovec/0.10.4/download\"],\n strip_prefix = \"zerovec-0.10.4\",\n build_file = Label(\"@crates//crates:BUILD.zerovec-0.10.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerovec-derive-0.10.3\",\n sha256 = \"6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerovec-derive/0.10.3/download\"],\n strip_prefix = \"zerovec-derive-0.10.3\",\n build_file = Label(\"@crates//crates:BUILD.zerovec-derive-0.10.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zmij-1.0.21\",\n sha256 = \"b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zmij/1.0.21/download\"],\n strip_prefix = \"zmij-1.0.21\",\n build_file = Label(\"@crates//crates:BUILD.zmij-1.0.21.bazel\"),\n )\n\n return [\n struct(repo=\"crates__argon2-0.5.3\", is_dev_dep = False),\n struct(repo=\"crates__dirs-5.0.1\", is_dev_dep = False),\n struct(repo=\"crates__libc-0.2.186\", is_dev_dep = False),\n struct(repo=\"crates__once_cell-1.21.4\", is_dev_dep = False),\n struct(repo=\"crates__openssl-0.10.68\", is_dev_dep = False),\n struct(repo=\"crates__parking_lot-0.12.5\", is_dev_dep = False),\n struct(repo=\"crates__parsec-client-0.16.0\", is_dev_dep = False),\n struct(repo=\"crates__serde-1.0.228\", is_dev_dep = False),\n struct(repo=\"crates__serde_json-1.0.150\", is_dev_dep = False),\n struct(repo=\"crates__tempfile-3.27.0\", is_dev_dep = False),\n struct(repo=\"crates__toml-0.8.19\", is_dev_dep = False),\n struct(repo=\"crates__zeroize-1.8.2\", is_dev_dep = False),\n struct(repo = \"crates__serial_test-3.5.0\", is_dev_dep = True),\n ]\n" } } }, @@ -11224,20 +11224,20 @@ "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"once_cell\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"alloc\",\n \"default\",\n \"race\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=once_cell\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\": [],\n \"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.21.4\",\n)\n" } }, - "crates__openssl-0.10.80": { + "crates__openssl-0.10.68": { "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", "attributes": { "patch_args": [], "patch_tool": "", "patches": [], "remote_patch_strip": 1, - "sha256": "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967", + "sha256": "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5", "type": "tar.gz", "urls": [ - "https://static.crates.io/crates/openssl/0.10.80/download" + "https://static.crates.io/crates/openssl/0.10.68/download" ], - "strip_prefix": "openssl-0.10.80", - "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"openssl\",\n deps = [\n \"@crates__bitflags-2.11.1//:bitflags\",\n \"@crates__cfg-if-1.0.4//:cfg_if\",\n \"@crates__foreign-types-0.3.2//:foreign_types\",\n \"@crates__libc-0.2.186//:libc\",\n \"@crates__openssl-0.10.80//:build_script_build\",\n \"@crates__openssl-sys-0.9.116//:openssl_sys\",\n ],\n proc_macro_deps = [\n \"@crates__openssl-macros-0.1.1//:openssl_macros\",\n ],\n aliases = {\n \"@crates__openssl-sys-0.9.116//:openssl_sys\": \"ffi\",\n },\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=openssl\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\": [],\n \"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.10.80\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n link_deps = [\n \"@crates__openssl-sys-0.9.116//:openssl_sys\",\n ],\n edition = \"2021\",\n pkg_name = \"openssl\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=openssl\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"0.10.80\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + "strip_prefix": "openssl-0.10.68", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_crypto'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"openssl\",\n deps = [\n \"@crates__bitflags-2.11.1//:bitflags\",\n \"@crates__cfg-if-1.0.4//:cfg_if\",\n \"@crates__foreign-types-0.3.2//:foreign_types\",\n \"@crates__libc-0.2.186//:libc\",\n \"@crates__once_cell-1.21.4//:once_cell\",\n \"@crates__openssl-0.10.68//:build_script_build\",\n \"@crates__openssl-sys-0.9.116//:openssl_sys\",\n ],\n proc_macro_deps = [\n \"@crates__openssl-macros-0.1.1//:openssl_macros\",\n ],\n aliases = {\n \"@crates__openssl-sys-0.9.116//:openssl_sys\": \"ffi\",\n },\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=openssl\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx800\": [],\n \"@rules_rust//rust/platform:x86_64-pc-nto-qnx800\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.10.68\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n link_deps = [\n \"@crates__openssl-sys-0.9.116//:openssl_sys\",\n ],\n edition = \"2021\",\n pkg_name = \"openssl\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=openssl\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"0.10.68\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" } }, "crates__openssl-macros-0.1.1": { diff --git a/score/cryptoki/Cargo.lock b/score/cryptoki/Cargo.lock index f873c9b5a..c89cbfd69 100644 --- a/score/cryptoki/Cargo.lock +++ b/score/cryptoki/Cargo.lock @@ -633,14 +633,15 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "openssl" -version = "0.10.80" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags", "cfg-if", "foreign-types", "libc", + "once_cell", "openssl-macros", "openssl-sys", ]