-
Notifications
You must be signed in to change notification settings - Fork 2
Significant revision of cask. Remove expiry. Reorder data. Eliminate CASK kind. #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -1,67 +1,83 @@ | |||
# CASK 256-bit Primary Keys | |||
# CASK Secrets |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A key CASK principle is for the core format to publish data that is useful for static consumption and not tempting to evaluate at runtime. And so we drop the expiry as too tempting for runtime evaluation.
Noice! I appreciate this principle and think it's a good change for the spec. I also appreciate the new disclaimer/caveat on restricting use case of the correlating-id
.
Overall looking good! 😊 🚀
Ping me once you publish the PR and I'll review/stamp again if @nguerrera doesn't beat me to it!
docs/CaskSecret.md
Outdated
# CASK Secrets | ||
## Standard Backus-Naur Form (BNF) | ||
``` | ||
<key> ::= <sensitive-data> <cask-signature> <timestamp> <sensitive-data-size> <optional-data-size> <provider-kind> [<optional-fields>] <provider-signature> <correlating-id> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Thinking out loud… Should the spec switch the ordering so <sensitive-data-size>
comes before timestamp
? Locating the size as close as possible to the cask-signature
and the sensitive-data
, for some unarticuable reason, feels more natural?
I don't have a strong technical argument to make the change though, so it's def a nit. #Pending
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we could do this. The unfortunate rough edge of the format is that there is a single element of the timestamp that leaks across the next 4-char encoded boundary.
Today, YMDHM precedes the next three encoded chars representing sensitive data size, optional data size and provider key kind. We made this choice because it effectively puts the provider key kind as a prefix to the provider signature, and that's very nice for regexes, other evaluation. So BAZST
, CAZST
, etc.
If we just said, well, let's do both, then we could have sensitive data size, optional data size, year and month in the first 3-byte segment, then day, hour, minute, provider key kind in the second. This PR already shows that these 6 bytes are best processed as a group, and the pattern here (I think) would be persistent even if we took this change, you'd just adjust the ordering of the various encoded/decoded char values.
Here's a bunch of blah blah and a proposal on this change, see what you think.
…ary code coverage review completed. Detailed first pass review not compete.
A small note on the PR description about something that came up during our chat that is very subtle and worth recording now before we forget about it.
I now believe scanning performance is only a secondary benefit. We could probably get good enough performance using only some well-known max lengths. I think the more fundamental benefit is being able to determine where a secret starts and ends without any dependency on the data before or after the secret. For scenarios like binary and memory dump scanning, this could be critical. #Resolved |
@@ -1,7 +1,7 @@ | |||
root = true | |||
charset = utf-8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We appear to have a file with a UTF8 BOM that is triggering the issue below. We can work around this for now by setting UTF8 as a default encoding (which means our mixture of UTF8 BOM + ASCII works). Alternately we could chase down the BOM and zap it (it may be in a project file, the issue below references BOMs being inserted in some project scenarios).
dotnet/sdk#46780 #Pending
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will look into this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That baton is yours.
|
||
public static byte ProviderKindToByte(char providerKind) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think tiny helpers that do things like x - 'A'
, * 3
and casts are still applicable and would still be nice to use. I find comments like // 'A' == index 0 of all printable base64-encoded characters.
in a larger method like IsCaskBytes
to be a hint to extract a helper, same as seeing 15
as a hint to extract a constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree! Pending future PR.
#47
/// <summary> | ||
/// A bit mask to obtain the reserved bits from the key kind. | ||
/// </summary> | ||
public const int CaskKindReservedMask = (1 << CaskKindReservedBits) - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've deleted a ton of constants and some exception helpers, based on code coverage and the general thought that anything that exists should have an explicit utilization in code.
I am not sure on the best way to replace our index/range constants. After the design update, all of this stuff needs to be computed dynamically. Basically, you first need to understand the size of the sensitive data component. This gives you the offset of the fixed cask signature, from which you can compute all remaining offsets.
#Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can still have constants for lengths. For example, I saw a wild 15
that could be CorrelationIdLengthInBytes
. Please check for others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted in #47
…ion to some polyfill classes).
…ion to some polyfill classes).
@@ -25,8 +25,8 @@ public interface ICask | |||
|
|||
string GenerateKey(string providerSignature, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's nice to no longer repeated parameter types (string followed by string in particular) to lead to unexpected ordering issues...
Here's a new FxCop rule: on observing any two sequential argument types which are the same, require that all call sites use named arguments to distinguish them (and raise visibility on calling mistakes). #Resolved
Yes, I copied this note into my bundle of comments that will support the spec draft, coming soon. In reply to: 2711260568 |
… security sensitive purposes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not a completed a full review pass yet. Saving my comments so far. There are some high-level things that I think are worth discussing and I don't think that discussion needs to wait for me to review all the details.
@@ -0,0 +1,92 @@ | |||
# CASK Secrets |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the pseudo-code as well. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, yes, done.
src/Cask/Cask.cs
Outdated
* 128-bit : 45 bytes (18 bytes sensitive + 27 reserved) : 12 bytes of optional data permissible < (60 - 45) | ||
* 256-bit : 60 bytes (33 bytes sensitive + 27 reserved) : 12 bytes of optional data permissible < (75 - 60) | ||
* 384-bit : 75 bytes (48 bytes sensitive + 27 reserved) : 15 bytes of optional data permissible < (93 - 75) | ||
* 512-bit : 93 bytes (66 bytes sensitive + 27 reserved) : 15 bytes (value chosen to align with 384 bit keys) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is 15 bytes actually allowed at all in practice? There is still a limit constant and it's set fixed to 12?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so my reply is that we enforce a 12 byte constraint today but that, if true, that means there is a specific 384-bit key in code that's forbidden where we have space for it. Let me go add a test and look for that bug,.
I've gone back and forth: should we permit the extra 3 bytes in 384 just because we can? if we do that, we should we allow 15 bytes in the longer key because it's weird to drop back the permissible optional data length for this one? or should we just say, 12 bytes only because that's simplest to explain?
I will add explicit tests that ensure we cover our intent thoroughly. Please let me know what you think that intent should be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
12 bytes max, period. That's my preference. 😊
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok! I will make it so. I can't resist noting here, that if we want the simplification of limiting all optional data to 12 bytes, that opens the possibility of us injecting 3 bytes of padding into the 384 bit key. the result of that is that we would always have at least 8 bits of reserved space in the format for some future use. it comes at the cost of artificially creating padding for the 384 bit key unnecessarily. that key is already long, the space wouldn't kill us. but adding this padding would be an unnecessary additional wrinkle/requirement we could avoid. thoughts?
src/Cask/Cask.cs
Outdated
return InferSensitiveDataSizeFromByteLength(lengthInBytes); | ||
} | ||
|
||
internal static SensitiveDataSize InferSensitiveDataSizeFromByteLength(int lengthInBytes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. I was expecting explicit lengths would prevent the need for this. But that doesn't actually work with the lengths placed in the middle of variable length things to either side. :(
If I were implementing this spec, when I got to this part, I would say, "What? Why are the lengths in the middle?"
Was putting the CASK signature at the front rather than the middle considered, and if so, why was it rejected? (This choice is carried over from prior formats and before my time so I genuinely don't know.)
If we had QJJQ at the front, followed by sizes, it would look just like a typical binary format where there's a header that starts with a signature and gives you info that you need to efficiently jump around the payload.
#Pending
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More thoughts than you wanted on this idea, let's discuss after this review.
#48
docs/CaskSecret.md
Outdated
; specify a particular cryptographic algorithm or method for | ||
; generating it. The size of this component must conform to the | ||
; encoded <sensitive-data-size> value. | ||
<128-bits-padded> ::= 21 * <base64url> <base64-four-zeros-suffix> 'AA' ; The total random data comprises 128 bits encoded as 21 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<128-bits-padded> ::= 21 * <base64url> <base64-four-zeros-suffix> 'AA' ; The total random data comprises 128 bits encoded as 21 | |
<128-bits-padded> ::= 21 * <base64url> <base64-four-zeros-suffix> 'AA' ; The total sensitive data comprises 128 bits encoded as 21 | |
``` #Resolved |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not going to comment on all of them, but there are several more occurrences of random
that should be sensitive
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes thanks
src/Cask/Cask.cs
Outdated
// Sensitive component size. | ||
key[SecretEntropyInBytes] = (byte)SensitiveDataSize.Bits256; | ||
Index endOfSensitiveComponent = sensitiveDataSizeInBytes - intPaddingBytes; | ||
FillRandom(key[..endOfSensitiveComponent]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently, the explicit writing of padding was removed in the previous change. I was surprised to not see it here.
We must not assume that stackalloc'ed memory is zero-ed out.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/stackalloc
The content of the newly allocated memory is undefined.
I think in practice with today's compilers, it will be zeroed out unless SkipLocalsInit
is used, but we should not rely on this undocumented behavior.
#Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh geez, ok, what could go wrong with undefined initialization behavior, it's worked out great for C++. :)
Haha. The previous explicit padding was removed when I adjusted this code for optional data sizes. I added this in the test decoding but not here, will do it.
{ | ||
int bytesWritten; | ||
Range caskSignatureByteRange = ComputeSignatureByteRange(sensitiveDataSize); | ||
CaskSignatureBytes.CopyTo(key[caskSignatureByteRange]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am thinking that it would be easier to follow if generate did not compute ranges, but instead bumped a destination span like a pointer to write each field.
I had done it this way originally but removed it when everything was constant, but now I regret that.
Something like this:
Span<byte> destination = key;
// Sensitive data.
FillRandom(destination[..SecretEntropyInBytes]);
destination = destination[SecretEntropyInBytes..];
// Padding.
destination[..paddingBytes].Clear();
destination = destination[paddingBytes..];
// Cask signature.
CaskSignatureBytes.CopyTo(destination[..3]);
destination = destination[3..];
// etc.
Now I don't need to compute the signature range, just know that I will be positioned at the signature after writing the fields that come before it. This follows the pseudo-code (although that isn't updated yet in this change) that just says "write X to the next N bytes".
#Pending
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still reviewing, but saving progress.
src/Cask/Cask.cs
Outdated
SensitiveDataSize sensitiveDataSize = InferSensitiveDataSizeFromCharLength(keyUtf8.Length); | ||
Range caskSignatureByteRange = ComputeSignatureCharRange(sensitiveDataSize); | ||
|
||
// Check for CASK signature. "QJJQ" base64-decoded. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment change is incorrect. We are examing base64-encoded data in UTF-8. #Resolved
src/Cask/Cask.cs
Outdated
// Check for CASK signature, "QJJQ" UTF-8 encoded. | ||
if (!keyUtf8[CaskSignatureCharRange].SequenceEqual(CaskSignatureUtf8)) | ||
SensitiveDataSize sensitiveDataSize = InferSensitiveDataSizeFromCharLength(keyUtf8.Length); | ||
Range caskSignatureByteRange = ComputeSignatureCharRange(sensitiveDataSize); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just name this caskSignatureRange
. It is a byte range, but usually wen we are talking about byte ranges we are talking about the base64-decoded form, not UTF-8. That may have cause the confusion that led to the comment change below, or maybe it was copy/paste. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
caskSignatureUtf8Range
src/Cask/Cask.cs
Outdated
// Check that kind is valid. | ||
if (!TryByteToKind(keyBytes[CaskKindByteIndex], out CaskKeyKind kind) || | ||
kind is not CaskKeyKind.PrimaryKey and not CaskKeyKind.DerivedKey and not CaskKeyKind.HMAC) | ||
int sensitiveDataSizeInBytes = RoundUpTo3ByteAlignment((int)encodedSensitiveDataSize * 16); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe name this paddedSensitiveDataSizeInBytes
or alignedSensitiveDataSizeInBytes
#Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in other code, i created a variable for entropySizeInBytes
then used sensitiveDataSizeInBytes
(because our definition for sensitive data size includes the padding.
i am nit-picking, but sensitive data size = padded entropy
by definition. i will add the additional local and then you tell me what you think about this not very important topic. :)
src/Cask/Cask.cs
Outdated
} | ||
|
||
int providerDataLengthInBytes = (minutesSizesAndKeyKindChars[2] - 'A') * 3; | ||
if (providerDataLengthInBytes > MaxProviderDataLengthInBytes || providerDataLengthInBytes % 3 != 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Is3ByteAligned helper #Resolved
src/Cask/Cask.cs
Outdated
int keyLengthInBytes = GetKeyLengthInBytes(providerDataLengthInBytes, sensitiveDataSize); | ||
|
||
int entropyInBytes = (int)sensitiveDataSize * 16; | ||
int sensitiveDataSizeInBytes = RoundUpTo3ByteAlignment(entropyInBytes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too I think it would be good to put padded
or aligned
in the name. I'm quickly losing track of the difference between these variables as I read on. #Resolved
src/Cask/Cask.cs
Outdated
|
||
// Sensitive component size. | ||
key[SecretEntropyInBytes] = (byte)SensitiveDataSize.Bits256; | ||
Index endOfSensitiveComponent = sensitiveDataSizeInBytes - intPaddingBytes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is the same as entropyInBytes, which could be used directly below. #Resolved
/// <summary> | ||
/// A bit mask to obtain the reserved bits from the key kind. | ||
/// </summary> | ||
public const int CaskKindReservedMask = (1 << CaskKindReservedBits) - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can still have constants for lengths. For example, I saw a wild 15
that could be CorrelationIdLengthInBytes
. Please check for others.
|
||
public static byte ProviderKindToByte(char providerKind) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think tiny helpers that do things like x - 'A'
, * 3
and casts are still applicable and would still be nice to use. I find comments like // 'A' == index 0 of all printable base64-encoded characters.
in a larger method like IsCaskBytes
to be a hint to extract a helper, same as seeing 15
as a hint to extract a constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I've made a full review pass now.
src/Cask/Cask.cs
Outdated
{ | ||
/* | ||
* Required CASK encoded data, 30 bytes. | ||
* QJJQ YMDH MLOP TEST 1234 1234 1234 1234 1234 1234 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this has 3 bytes/4 chars too many in C3ID and the total should be 27 bytes, not 30. 27 reserved
in comment below doesn't match 30
above.
It would be nice to put these in constants, like Min(256|384|512Bit)KeyLengthInBytes
.
#Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woof, yes, this area moved around a little. Fixed, thanks.
src/Cask/Cask.cs
Outdated
return SensitiveDataSize.Bits256; | ||
} | ||
|
||
return SensitiveDataSize.Bits128; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider switch expression:
return lengthInBytes switch
{
>= Min512BitKeyLengthInBytes => SensitiveDataSize.Bits512,
>= Min384BitKeyLengthInBytes => SensitiveDataSize.Bits384,
>= Min256BitKeyLengthInBytes => SensitiveDataSize.Bits256,
_ => SensitiveDataSize.Bits128,
}; #Resolved
src/Cask/Helpers.cs
Outdated
const int uppercaseZIndex = 'Z' - 'A'; | ||
const int lowercaseZIndex = 'z' - 'a'; | ||
int entropyInBytes = (int)sensitiveDataSize * 16; | ||
int sensitiveDataSizeInBytes = RoundUpTo3ByteAlignment(entropyInBytes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should no longer refer to entropy
unless we are generating a random key. Again, the real distinction between these two is padded vs. unpadded and the names are making that hard to see. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed everywhere. Also changed many names from 'sensitiveDataSize' to 'secretSize'. Arg. Why did I include that rename here? :P
src/Cask/Helpers.cs
Outdated
kind = default; | ||
return false; | ||
} | ||
keyLengthInBytes += sensitiveDataSizeInBytes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also find the mutation of keyLengthInBytes confusing. I guess this is to save some horizontal space, but there's no real reason to have an intermediate partial keyLengthInBytes. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simplified.
src/Cask/SensitiveDataSize.cs
Outdated
|
||
/// <summary> | ||
/// Specifies a computed value with one 16-byte | ||
/// (128 bit) segment of entropy. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/entropy/sensitive data/
Many instances of this in this file, but I will only comment once. #Resolved
src/Tests/Cask.Tests/CaskKeyTests.cs
Outdated
} | ||
internal static SensitiveDataSize[] AllSensitiveDataSizes => [ | ||
SensitiveDataSize.Bits128, SensitiveDataSize.Bits256, | ||
SensitiveDataSize.Bits384, SensitiveDataSize.Bits512]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, I'd put each of these on their own line. #Resolved
@@ -1,7 +1,7 @@ | |||
root = true | |||
charset = utf-8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will look into this.
Co-authored-by: Nick Guerrera <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review of pseudo-code only. Now reviewing the rest since last review.
docs/GenerateKeyPseudoCode.md
Outdated
- Provider data (if non-empty) consists entirely of base64url printable characters. | ||
- Secret data size is between 1 (indicating a 128-bit component) and 4 (indicating 512-bits). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not listed as an input. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nuts and expiry not deleted. Let's fix this before checking in.
docs/GenerateKeyPseudoCode.md
Outdated
- Provider data (if non-empty) consists entirely of base64url printable characters. | ||
- Secret data size is between 1 (indicating a 128-bit component) and 4 (indicating 512-bits). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can discuss separately from this PR, but I think we should consider making this a size in bytes or bits. And then specify the required alignment and min/max to validate. If someone decided to implement this without an enum, it would be really weird and hard to use IMHO. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More accurately, this value is a count of 16-byte segments in the secret data. Just as our optional data value is a count of 3-byte segments. I updated the language. Glad to continue discussing this.
docs/GenerateKeyPseudoCode.md
Outdated
1. Let N = the length of the base64url-decoded provider data. | ||
- Number of characters in provider data divided by 4, times 3. | ||
1. Compute the sensitive data size in bytes: | ||
- Multiply the secret data size by 16. | ||
- Round this value up to the next multiple of 3, if necessary. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can leave this for now, but I'm finding it hard to understand that this does not mean to discard the unrounded value, that you actually do need later. Maybe it would be better to specify how to compute how many bytes to pad separately. #Pending
return InferSensitiveDataSizeFromByteLength(lengthInBytes); | ||
} | ||
|
||
private static SecretSize InferSensitiveDataSizeFromByteLength(int lengthInBytes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: rename here too?
private static SecretSize InferSensitiveDataSizeFromByteLength(int lengthInBytes) | |
private static SecretSize InferSecretSizeFromByteLength(int lengthInBytes) |
This significant revision of CASK contains the following changes:
QJJQ
we enable high-performance detections that start with locating the CASK signature in test/data streams.The BNF is renamed to
CaskSecrets.md
to reflect that there's no longer a specific CASK key kind in play. The churn in the BNF was sufficient that rather than renaming first so that we could diff, I simply created a clean copy of the new BNF. But in case anyone finds it helpful to see the explicit diffs from previous, I've left an edited version of the old BNF behind to examine. This will be deleted, obviously, once everything is reviewed/refined/accepted.This change resolved #35, #36 and #37.