GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-99108: add HACL*-based 1-shot HMAC implementation by picnixz · Pull Request #126359 · python/cpython

Conversation

@picnixz

@picnixz picnixz commented Nov 3, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

I'm opening a PR but I'm pretty sure that there are multiple things to discuss:

  • HACL* HMAC requires including hash functions headers (by the way, SHA1 and MD5 headers are not included in Hacl_HMAC.h, but they are included in the .c; you might want to check that on your side @msprotz).
  • I decided to create static intermediate libraries just. Otherwise, I'm getting a bunch of "undefined symbols". I know that we have a simplification PR (gh-116043: Simplify HACL* build #119320) to get rid of *.a. The reason I kept (and used) them is the following:
    • When I use normal dependencies in Setup.stdlib.in, I get a bunch of warnings "Makefile:3471: warning: overriding recipe for target 'Modules/_hacl/Hacl_Hash_MD5.o" for instance.
    • In addition, I don't know how to specify that the HMAC module should use libHacl_Hash_Blake2.a (I get "gcc: error: Modules/_hacl/libHacl_Hash_Blake2.a: No such file or directory").
      The build I suggest compiles on my machine and I would appreciate if @erlend-aasland could help me in cleanng it up.

I'm leaving my dev session in a few hours and won't be back until Wednesday. I need to test the implementatino as well (for SHA1, I think something is weird because I get different results, well mainly junk at the end but I'll need to check again when I'm back).

  • Issue: Replace built-in hashlib with verified implementations from HACL* #99108

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@picnixz
Pull HACL* HMAC.
6336160
HACL* is at revision fc2e38f4d899ba28665c5b91caedaf35b3b37452.
@bedevere-app bedevere-app Bot mentioned this pull request Nov 3, 2024
Replace built-in hashlib with verified implementations from HACL* #99108
Closed
@picnixz picnixz added the skip news label Nov 3, 2024
@picnixz

picnixz commented Nov 3, 2024

Copy link
Copy Markdown
Member Author

Adding skip news for now just for the CI to be green.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@picnixz
picnixz force-pushed the hacl/HMAC-99108 branch 5 times, most recently from ca5e851 to d6c92a6 Compare November 3, 2024 13:19
@picnixz

picnixz commented Nov 3, 2024

Copy link
Copy Markdown
Member Author

@msprotz The following code is not liked by MSVC:

  uint32_t l = 64U;
  KRML_CHECK_SIZE(sizeof (uint8_t), l);
  uint8_t key_block[l]; // <- this

I wonder whether you can do something (like inlining the variable instead) or tell me if it's possible to make MSVC happy.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

picnixz added 6 commits November 3, 2024 14:27
@picnixz
Update SBOM files
5a410f8
@picnixz
Update HACL (CPython) namespace
c1c7c92
@picnixz
Update HACL (CPython) README
2901987
@picnixz
Update configure script
92a1e76
@picnixz
Update Makefile scripts
027964b
@picnixz
Update MSVC project
17a2e46
@picnixz
picnixz force-pushed the hacl/HMAC-99108 branch from d6c92a6 to 66c6a25 Compare November 3, 2024 13:27
@picnixz
Implement HACL* HMAC module
186094b
@picnixz
picnixz force-pushed the hacl/HMAC-99108 branch from 66c6a25 to 186094b Compare November 3, 2024 13:35
@picnixz
picnixz marked this pull request as ready for review November 3, 2024 14:20
@picnixz
picnixz requested review from a team, corona10, ericsnowcurrently, erlend-aasland, gpshead and sethmlarson as code owners November 3, 2024 14:20
@bedevere-app bedevere-app Bot added the awaiting review label Nov 3, 2024
@picnixz

picnixz commented Nov 3, 2024

Copy link
Copy Markdown
Member Author

I'm marking this PR as ready for review even though it fails to build on Windows. We'll address that later (for now, I want to get feedback on the build itself and how to get rid of .a files).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ZeroIntensity
ZeroIntensity reviewed Nov 3, 2024
View reviewed changes

@ZeroIntensity ZeroIntensity left a comment

Copy link
Copy Markdown
Member

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.

Sometime I forget that you're a cryptography genius 😅

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Modules/hmacmodule.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/hmacmodule.c
PyMODINIT_FUNC
PyInit__hmac(void)
{
return PyModuleDef_Init(&_hmacmodule);

@ZeroIntensity ZeroIntensity Nov 3, 2024

Copy link
Copy Markdown
Member

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 is primarily a note for myself when this is closer to being ready.)

Do modules without a m_traverse get to use DRC to ease contention (which will be especially bad here because of the critical sections)? If not, force the module to do that, or consider making this immortal somehow. (I'll follow up on this--it will take some work, because I don't think we're doing it anywhere else in the stdlib.)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@picnixz picnixz Nov 7, 2024

Copy link
Copy Markdown
Member Author

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.

(For others: DRC means deferred reference count). This is something I also wondered, namely should I explicitly call Py_VISIT(Py_TYPE(mod)) even if I don't have a state or not? I assume not because that's what multiple modules with m_size = 0 do as well. I don't know where to find an exact reference on that behaviour though.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Modules/hmacmodule.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

@Nankunda489 Nankunda489 mentioned this pull request Nov 3, 2024
Dashboard #126368
Closed
picnixz added 3 commits November 11, 2024 12:55
@picnixz
expose 1-shot HMAC
9bee955
@picnixz
ensure that openssl is linked
d36977f
@picnixz
update globals
b3aa599
@picnixz

picnixz commented Nov 11, 2024

Copy link
Copy Markdown
Member Author

Ok, I need to think of a way to easily map hashlib<->openssl dispatch for HMAC. Converting into a draft for now.

ZeroIntensity reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@picnixz
picnixz marked this pull request as draft November 11, 2024 12:39
@bedevere-app bedevere-app Bot removed the awaiting review label Nov 11, 2024
@msprotz

msprotz commented Nov 11, 2024

Copy link
Copy Markdown
Contributor

Just to set expectations, @R1kM and I looked at what it would take to add streaming HMAC and we're relatively confident that it can be done within a few weeks. We have a couple more urgent things, then we'll get to it and post here as soon as we have an update, and then it'll simplify everything to have a single implementation that can do streaming too.

gpshead reacted with hooray emoji
All reactions
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

picnixz added 4 commits November 12, 2024 11:11
@picnixz
fix LN_* macro values
49a1294
@picnixz
improve OpenSSL name resolution
06b012d
@picnixz
update comment
82c610c
@picnixz
fix configure?
ff8cf2f
@picnixz

picnixz commented Nov 12, 2024

Copy link
Copy Markdown
Member Author

Ok, so I managed to fix the compilation and find a nice way to resolve OpenSSL names. However, since I need to bind OpenSSL for Windows builds, I'd like someone to create the project files for Windows since I don't have .NET installed (and honestly I don't want to install it; I could use a VM if I have time). So I'll just ignore the Windows build failures for now.

I looked at what it would take to add streaming HMAC and we're relatively confident that it can be done within a few weeks

No hurry, take your time! It'd be nice if the API for all HMAC-HASH functions are the same (or at least, that the functions can be stored using the same function pointer type).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@msprotz

msprotz commented Nov 12, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

It'd be nice if the API for all HMAC-HASH functions are the same (or at least, that the functions can be stored using the same function pointer type).

There are two styles of APIs, and we're not sure yet which one we want to go for. Your feedback is most welcome.

Agile APIs are of the form struct state { union { uint64_t *sha2_512_state; uint32_t *sha2_256 state; .... } hash_state; seen: uint64_t; hash_alg a; } void update(state *s, uint8_t *input, uint32_t input_len);

  • a single update function for all choices of algorithms
  • choice of algorithm is provided at state allocation-time (i.e. void malloc(hash_alg a);)
  • extra level of indirection in the state due to the need to have a tagged union

Plain APIs are of the form typedef uint64_t *sha2_512 state; void update_512(sha2_512 *state, uint8_t *input, uint32_t input_len); and come in different variants (and different types) for all algorithms, i.e. there's also typedef uint32_t *sha2_256 state; void update_256(sha2_256 *state, uint8_t *input, uint32_t *input_len);, etc.

  • one update function for each algorithm
  • client manages the choice of algorithm (possibly keeping a tagged union themselves, or function pointers, whatever their style is)
  • no extra level of indirection
  • massive code duplication since each algorithm re-implements the state management logic

Thoughts on which one you'd prefer?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@picnixz

picnixz commented Nov 12, 2024

Copy link
Copy Markdown
Member Author

Thank you for the reply! Some questions:

massive code duplication since each algorithm re-implements the state management logic"

I assume however that performances are slightly better since you don't have indirection, right? How better do they fare in general? are plain APIs really better than agile ones?


Agile API seems good because I only need to specify the hash_alg value and be done with that. I'll need to think a bit more on that but I'm leaving for today and won't be available until tomorrow. I'll try to find a good example of how I plan to use it and then I'll come back to you!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@msprotz

msprotz commented Nov 12, 2024

Copy link
Copy Markdown
Contributor

I assume however that performances are slightly better since you don't have indirection, right? How better do they fare in general? are plain APIs really better than agile ones?

generally there's no noticeable performance impact unless you repeatedly hmac a lot of very small data, and repeatedly create/destroy the underlying python object, meaning you end up calling malloc/free a lot

the plain APIs exist for engineering reasons: you can package a single hmac algorithm along with its plain API, but if the agile API is the only API offered, a client like Python has to take all of the hmac algorithms in one go (since the toplevel agile API now contains references to every individual algorithm)

if you intend to overhaul all of the hmac algorithms in one go, then I would do agile API

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@picnixz

picnixz commented Nov 15, 2024

Copy link
Copy Markdown
Member Author

FTR, I have a branch with streaming HMAC: https://github.com/picnixz/cpython/tree/hacl/HMAC-stream-99108. For now, I'm assuming that I have a plain API that can be used as follows:

/* Function pointer type for HACL* streaming HMAC state allocation */
typedef void *(*HACL_HMAC_state_malloc_func)(void);
/* Function pointer type for HACL* streaming HMAC state deallocation */
typedef void (*HACL_HMAC_state_free_func)(void *state);
/* Function pointer type for HACL* streaming HMAC state copy */
typedef void *(*HACL_HMAC_state_copy_func)(void *state);

/* Function pointer type for HACL* streaming HMAC setup functions. */
typedef hacl_exit_code
(*HACL_HMAC_setup_func)(void *state, uint8_t *key, uint32_t len);
/* Function pointer type for HACL* streaming HMAC update functions. */
typedef hacl_exit_code
(*HACL_HMAC_update_func)(void *state, uint8_t *buf, uint32_t len);
/* Function pointer type for HACL* streaming HMAC digest functions. */
typedef hacl_exit_code
(*HACL_HMAC_digest_func)(void *state, uint8_t *out);
  • HACL_HMAC_state_malloc_func would allocate me the state for the HMAC-H algorithm
  • HACL_HMAC_state_free_func would allow me to free it
  • HACL_HMAC_state_copy_func would allow me to clone it
  • HACL_HMAC_setup_func would allow me to feed the state with the user key (given at construction time). No message is given at that moment yet.
  • HACL_HMAC_update_func would allow me to feed data in a streaming fashion.
  • HACL_HMAC_digest_func would allow me to extract the digest from the state and putting it in out.

Ideally, I would like to expose the transformation function $f\colon\left\{0,1\right\}^*\longrightarrow\left\{0,1\right\}^B$ where $B$ is the block size so that users can also pass keys whose length exceeds $2^{32}-1$ or pad keys.

For now, the branch I mentioned assumes that the state consists of the message until now and the key (just to make it work).


Now, using an agile API, I could lighten the current interface to avoid storing those function pointers and only store the hash_alg. However, I'd like to be able to feed the initial key without having to feed the message, as well as the possibility to clone a state (since we have a .copy() method).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

picnixz added 6 commits November 15, 2024 10:23
@picnixz
Merge remote-tracking branch 'upstream/main' into hacl/HMAC-99108
7af7eb6
@picnixz
sbom
fba3778
@picnixz
remove unused imports
5c3cbfd
@picnixz
cosmetic changes for future resolution
379cbef
@picnixz
fix memory leak
960aa73
@picnixz
add #define for error messages
074f9ab
@msprotz

msprotz commented Dec 2, 2024

Copy link
Copy Markdown
Contributor

I'm coming back online after being off last week. Made some good progress on an agile HMAC interface, hopefully first prototype by the end of the week. It will be agile, meaning you won't have to deal with function pointers, the dynamic dispatch will be internal. The malloc function will take an algorithm and a key, and you will also have access to the copy function you mentioned. This should all greatly simplify your life.

Hoping to send a link to the PR soon.

gpshead reacted with heart emoji
All reactions
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@picnixz

picnixz commented Dec 2, 2024

Copy link
Copy Markdown
Member Author

The malloc function will take an algorithm and a key, and you will also have access to the copy function you mentioned. This should all greatly simplify your life.

That would be perfect! Thanks in advance!

I still need to know how I can make the Windows build work :( But I should have prepared everything to support the agile API.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@msprotz msprotz mentioned this pull request Dec 3, 2024
Incremental (streaming) HMAC hacl-star/hacl-star#1007
Merged
@picnixz

picnixz commented Dec 17, 2024

Copy link
Copy Markdown
Member Author

Just for those subscribed to this pull request. I plan to re-open a fresh one using picnixz/cpython@feat/hmac/hacl-99108 in order to incorporate both streaming and 1-shot HMAC at the same time. However, we can continue the design discussion on this PR until the HACL* part is done.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@picnixz picnixz mentioned this pull request Feb 15, 2025
gh-99108: Implement HACL* HMAC #130157
Merged
@picnixz

picnixz commented Feb 15, 2025

Copy link
Copy Markdown
Member Author

Closing in favor of #130157.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@picnixz picnixz closed this Feb 15, 2025
@picnixz
picnixz deleted the hacl/HMAC-99108 branch March 3, 2025 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@gpshead gpshead gpshead left review comments
@zooba zooba zooba left review comments
@ZeroIntensity ZeroIntensity ZeroIntensity left review comments
@sethmlarson sethmlarson Awaiting requested review from sethmlarson sethmlarson is a code owner
@ericsnowcurrently ericsnowcurrently Awaiting requested review from ericsnowcurrently ericsnowcurrently is a code owner
@erlend-aasland erlend-aasland Awaiting requested review from erlend-aasland erlend-aasland is a code owner
@corona10 corona10 Awaiting requested review from corona10 corona10 is a code owner
@AA-Turner AA-Turner Awaiting requested review from AA-Turner AA-Turner will be requested when the pull request is marked ready for review AA-Turner is a code owner
@emmatyping emmatyping Awaiting requested review from emmatyping emmatyping will be requested when the pull request is marked ready for review emmatyping is a code owner
@itamaro itamaro Awaiting requested review from itamaro itamaro will be requested when the pull request is marked ready for review itamaro is a code owner
+1 more reviewer
@msprotz msprotz msprotz left review comments
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

skip news

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@picnixz @msprotz @gpshead @zooba @ZeroIntensity
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.