| // Copyright 2024 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| // use this file except in compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| // License for the specific language governing permissions and limitations under |
| // the License. |
| |
| // This is a DiceGenerateCertificate implementation that generates a CWT-style |
| // CBOR certificate using the P-256 signature algorithm. |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| #include <string.h> |
| |
| #include "dice/cbor_writer.h" |
| #include "dice/dice.h" |
| #include "dice/ops.h" |
| #include "dice/ops/trait/cose.h" |
| #include "dice/utils.h" |
| |
| #if DICE_PUBLIC_KEY_SIZE != 64 |
| #error "64 bytes needed to store the public key." |
| #endif |
| #if DICE_SIGNATURE_SIZE != 64 |
| #error "64 bytes needed to store the signature." |
| #endif |
| |
| DiceResult DiceCoseEncodePublicKey( |
| void* context_not_used, const uint8_t public_key[DICE_PUBLIC_KEY_SIZE], |
| size_t buffer_size, uint8_t* buffer, size_t* encoded_size) { |
| (void)context_not_used; |
| |
| // Constants per RFC 8152. |
| const int64_t kCoseKeyKtyLabel = 1; |
| const int64_t kCoseKeyAlgLabel = 3; |
| const int64_t kCoseKeyAlgValue = DICE_COSE_KEY_ALG_VALUE; |
| const int64_t kCoseKeyOpsLabel = 4; |
| const int64_t kCoseKeyOpsValue = 2; // Verify |
| const int64_t kCoseKeyKtyValue = 2; // EC2 |
| const int64_t kCoseEc2CrvLabel = -1; |
| const int64_t kCoseEc2CrvValue = 1; // P-256 |
| const int64_t kCoseEc2XLabel = -2; |
| const int64_t kCoseEc2YLabel = -3; |
| |
| struct CborOut out; |
| CborOutInit(buffer, buffer_size, &out); |
| CborWriteMap(/*num_pairs=*/6, &out); |
| // Add the key type. |
| CborWriteInt(kCoseKeyKtyLabel, &out); |
| CborWriteInt(kCoseKeyKtyValue, &out); |
| // Add the algorithm. |
| CborWriteInt(kCoseKeyAlgLabel, &out); |
| CborWriteInt(kCoseKeyAlgValue, &out); |
| // Add the KeyOps. |
| CborWriteInt(kCoseKeyOpsLabel, &out); |
| CborWriteArray(/*num_elements=*/1, &out); |
| CborWriteInt(kCoseKeyOpsValue, &out); |
| // Add the curve. |
| CborWriteInt(kCoseEc2CrvLabel, &out); |
| CborWriteInt(kCoseEc2CrvValue, &out); |
| // Add the subject public key x and y coordinates |
| CborWriteInt(kCoseEc2XLabel, &out); |
| CborWriteBstr(/*data_size=*/DICE_PUBLIC_KEY_SIZE / 2, &public_key[0], &out); |
| CborWriteInt(kCoseEc2YLabel, &out); |
| CborWriteBstr(/*data_size=*/DICE_PUBLIC_KEY_SIZE / 2, |
| &public_key[DICE_PUBLIC_KEY_SIZE / 2], &out); |
| |
| *encoded_size = CborOutSize(&out); |
| if (CborOutOverflowed(&out)) { |
| return kDiceResultBufferTooSmall; |
| } |
| return kDiceResultOk; |
| } |