Project

General

Profile

[logo] 
 
Home
News
Activity
About/Contact
Major Tools
  Dinotrace
  Verilator
  Verilog-mode
  Verilog-Perl
Other Tools
  IPC::Locker
  Parallel::Forker
  Voneline
General Info
  Papers

RFC: DPI encapsulated Verilog instead of encryption

Added by Todd Strader 4 months ago

Please see: https://github.com/toddstrader/dpi-compile

Any comments are welcomed, but I'd specifically like to ask about verilating to C++ with constructor-time parameters. First off, is this a reasonable thing to imagine? I am aware it would be a large lift. Secondly, would it be something that would be welcomed in the project?

As far as implementation goes, I would expect to see some of the static elaboration being deferred until the C++ instance is constructed. I can envision that for if/case generate blocks one would build code for all the options. Then at constructor time you would pick which path you were always going to take. Of course, this would make it difficult/impossible to schedule and prune things optimally. Generate loops would be more interesting. I think we'd want to have subclasses to represent the generated block and then building a vector of these instances during construction.

If there is an easier way to accomplish the above without making a change this large, I'd love to discuss that too. But I'm not sure how else to solve this problem. Of course, one could build a library for each permutation of parameters that is needed. But this quickly becomes untenable once the parameter space is big enough and/or requires an unwanted interaction between IP providers and users.

I also saw this: https://www.veripool.org/boards/2/topics/911-Verilator-How-to-set-the-value-of-a-corresponding-verilog-parameter-in-the-generated-C-code but figured it was worth seeing how thinking has evolved in the past seven years.

And in the end, perhaps this probably relates back to modular builds: https://www.veripool.org/boards/2/topics/412-Verilator-verilating-compiling-modules-into-separate-object-files

If we had something like that, I imagine at least some of the complexity of constructor-time parameters would go away.


Replies (5)

RE: RFC: DPI encapsulated Verilog instead of encryption - Added by Wilson Snyder 4 months ago

I am very skeptical on constructor-time parameters as a feature, both in terms of the technical problems involved (what if a "generate if" selects a module that doesn't have sources), the opportunity cost versus other features, and the maintenance support cost relative to the number of users that would required.

Note the current implementation delays some parameter processing (e.g. "generate if" inclusion of modules), and this has resulted in several bugs compared to other simulators, e.g. bug1314, bug1454). My long term thoughts had been to fix these by even more immediate parameter processing, not more deferring.

Can you describe why this is needed, and what solution is being used instead by you today? I haven't done a study in a while, but AFAIK the other simulators don't support this (which suggests hardness and/or lack of market).

As to the repo you mention:

Is there a specific requirement for the DPI to be involved, e.g. because this goes under another simulator, or was this just a convenience?

Some work was done in the embedding area with good signs of life, see this:

https://www.veripool.org/boards/3/topics/2348-Verilator-Adding-foreign-module-support-to-Verilator

This code needs to be re-based, but the fundamentals seem good and if I had more time would work on it. One thing I like about this approach was that the wrapper generated is Verilog. I think it could use the DPI and even have a wrapper runnable in other simulators if need be.

There's also test_regress/t/t_embed* in the repo which is a handwritten example of something similar.

Once such a "foreign" method is available it should not be difficult to add additional support for protect, i.e. a protect becomes an automagic foreign when protecting, and use of a foreign when using the protected. I think this is also what you are suggesting.

Note protect support is on the long term Verilator roadmap, there is interest, and welcome development in this and foreign support. I poked two companies about this and they thought that they would probably accept such a scheme as "protected", with the additional requirement of hashing/encrypting all of the internal symbols, as currently "objdump" of the resulting archive would otherwise give strong hints about the internal Verilog hierarchy.

RE: RFC: DPI encapsulated Verilog instead of encryption - Added by Wilson Snyder 4 months ago

P.S. Adding a hash of symbols could easily be added as an option in V3Name stage, and there's already a cryto hash in the code base. So, this would be a quick & easy project orthogonal to the larger protect project.

RE: RFC: DPI encapsulated Verilog instead of encryption - Added by Todd Strader 4 months ago

Can you describe why this is needed

For example, Xilinx provides the simulation model of its DSP as encrypted Verilog: https://www.xilinx.com/support/documentation/ip_documentation/xbip_dsp48_macro/v3_0/pg148-dsp48-macro.pdf

I believe the repo I posted shows that with reasonably little additional effort, a tool could be made so that Xilinx could compile a DPI-wrapped library of this or any module (assuming fixed top-level parameters). The problem is that the module has many parameters. So assuming one could convince Xilinx to play along, I see three options for dealing with these parameters:
  1. Xilinx compiles libraries for the cross product of all parameters (this is not realistic given the parameter space)
  2. End users request compiled libraries for their given parameters from Xilinx (seems unlikely given the support burden)
  3. Xilinx ships a tool (or part of Vivado) which will decrypt its own IP, feed it to this tool (given fixed parameters from the user) and spit out the compiled library

The last one is perhaps possible, but I'm pretty skeptical. If they were to just exec Verilator there are clear attack vectors since this would be running on the end user's machine. There might be ways to securely handle this with encrypted VMs, but I'm honestly not sure and that sounds pretty complicated.

and what solution is being used instead by you today?

Mostly shaking my fist at the world. Obviously I can't simulated encrypted Verilog with Verilator. Without an approach like this one is left to:
  • Use a commercial simulator to simulate encrypted logic
  • Attempt to build an analogous behavior model
  • Try to get the unencrypted source via NDA, etc.

I haven't done a study in a while, but AFAIK the other simulators don't support this (which suggests hardness and/or lack of market).

Support what? The DPI? All DPI-capable simulators should be able to use the library. Granted, I haven't tried this, but it's one motivation behind using the DPI here.

If you're referring to the ability to generate the library, we only need Verilator to be able to do that.

Is there a specific requirement for the DPI to be involved, e.g. because this goes under another simulator, or was this just a convenience?

I see this as a carrot + stick approach. I'd like to have a pathway which would allow IP providers to give me protected IP which is usable by Verilator. So on one hand, I really only care about getting this functionality to Verilator because I have mechanisms today for commercial simulators. But simultaneously, encrypted RTL is just broken and IP providers should be concerned about leaking plaintext RTL. Using the DPI here makes the approach broadly usable by all simulators and may incentivize IP providers to adopt it. Also, using the DPI was really simple and just works out of the box with Verilator today (if you can lock down top-level parameters).

Some work was done in the embedding area with good signs of life, see this: https://www.veripool.org/boards/3/topics/2348-Verilator-Adding-foreign-module-support-to-Verilator

I started reading through the patch, but I'll have to pull it down and play with it some too.

I poked two companies about this and they thought that they would probably accept such a scheme as "protected"

Does the foreign module patch allow for VPI access to or tracing of the foreign modules? That would be handy for modular building (which I would also love to see) but it would be counter to IP protection. Would you support the latter by enabling the compiler of the foreign module to select if they wanted this kind of introspection or not? I thought using the DPI was handy in this case because it makes it extremely clear what the surface area of the library is and it's very easy to reason about what you are and are not exposing.

with the additional requirement of hashing/encrypting all of the internal symbols, as currently "objdump"

Agreed. My example was not meant to be exhaustive (however you definitely can't get the RTL out of it). In the end, the library would only need the DPI function symbols to be recognizable. Everything else should be stripped, obfuscated, etc.

RE: RFC: DPI encapsulated Verilog instead of encryption - Added by Wilson Snyder 4 months ago

Thanks, now I understand, you're not really directly wanting runtime parameters. You want wanting protected models and see runtime parameters as a step to that.

You probably know this, but the way (all AFAIK) commercial simulators work is they encrypt the source or AST model with a key, and the parameters in the protected model are just like any other source code; the later embedding of the encrypted model decrypts then does elaboration. That is, the generation of a protected model is NOT elaborating and compiling to a representation that supports different runtime parameters, it's just representing the source in the before elaboration form.

I believe the repo I posted shows that with reasonably little additional effort, a tool could be made so that Xilinx could compile a DPI-wrapped library of this or any module (assuming fixed top-level parameters).

Agreed, and this seems technically straightforward (not to suggest minimal effort) along the lines of the approaches/repo we discussed.

I see three options for dealing with these parameters:

Another option is to remove as many parameters as possible. Looking at the Xilinx list most of the things that are parameters for simulation could probably easily be input wires (they aren't that way in the design presumably so that the gate ripper will remove them in the real FPGA.) The remaining list of parameters seems small, mostly (all?) the width of some buses. There is presumably some maximum supported, e.g. 256, so you could change the code to that width, then provide a wire input saying how many are really in use. Of course some non-trivial changes would be needed to code that way.

(Aside: BTW I commonly see people use parameters where wires are a much much better option; any good gate ripper can also remove logic controlled by wires tied to a constant. Wires are also beneficial when testing IP it's often a lot more efficient for runtime to compile a model just once and wiggle wires, than having to compile a model for each parameter choice.)

My main objection to the parameter scheme is moving data type resolution to runtime, which I still think is technologically hard and unattractive. I could however imagine an option which automates what I'm describing above, that is the user provides an e.g. parameter map providing all legal values for each parameter. Verilator follows the parameter use and tries to convert to wires where possible. Where parameters change data types, Verilator requires the user to say what to assume for the width. I'm not sure how automate-able this will be, but it's possible, I suspect. I don't think it will end up perfect, but if you can get down to just a few exceptions e.g. some manual width fixes, that might be good enough.

I know many vendors that provide encrypted code that doesn't have parameters, that is they have a tool to generate the user's exact model at the IP site or at the customer (they do your option 2 & sometimes 3). So, having such parameter-replace automation seems a better later step over the basic protect/embed, as some IP people won't need it.

I haven't done a study in a while, but AFAIK the other simulators don't support this (which suggests hardness and/or lack of market).

Support what? The DPI?

I was referring to runtime resolution of parameters. As discussed above, what they do support is a encrypting before parameters are elaborated.

I agree they also support the DPI.

Thinking about your point, I agree having Verilator able to produce/consume a "protected" DPI model makes a lot of sense. It can be used on any simulator would be greatly beneficial to vendors, as they can Verilate just once. Today they need to custom encrypt and test against each simulator vendor they support uniquely (though SV made the protection input more compatible it's still effectively necessary to build, test and qualify for each target).

Does the foreign module patch allow for VPI access to or tracing of the foreign modules? That would be handy for modular building (which I would also love to see) but it would be counter to IP protection. Would you support the latter by enabling the compiler of the foreign module to select if they wanted this kind of introspection or not?

Yes, I'd suggest at compile time the user chooses if tracing is allowed and what signals are traced (using existing pragmas/--trace options/etc). The signal name could either be plaintext or encrypted in V3Name (i.e. users could see the toggles but not the real signal name/scope. On a bug, the model owner would get the VCD, and deencrypt the VCD signal names to see the real signal name.)

A DPI call would turn on/off tracing, calling into the encrypted model's trace routines (from Verilator). Until we get fancier each instantiation could just make its own dumpfile. Long term could combine in one dump, but then have to be careful of problems from having different versions of the Verilator tracing libraries that might conflict.

Another option long term would be to add a encryption key to the generated waves file. Someone can reverse-engineer to get that key, but does provide some protection for the waves file being mailed around etc.

BTW I would avoid bringing the VPI into it as much as we can, as it complicates things, and AFAIK there's no way for the external model to "add symbols" to another simulator's VPI, so VPI is unlikely to help the tracing problem. (Verilator's internals allow adding to the VPI structures but that's not VPI standard.) For hierarchical embedding of Verilator-in-Verilator (verus encryption or Verilator-in-another-sim) we probably do want to allow a single VPI hierarchy showing all models; this should almost fall out of how Verilator's VPI works now which allows multiple Verilated models to be instantiated and share in one global VPI hierarchy.

RE: RFC: DPI encapsulated Verilog instead of encryption - Added by Todd Strader 4 months ago

That is, the generation of a protected model is NOT elaborating and compiling to a representation that supports different runtime parameters, it's just representing the source in the before elaboration form.

Yup, which is one advantage of this approach since the source never has to leave the IP provider (encrypted or not).

I see three options for dealing with these parameters:

While I'm imagining things here, I'll describe a fourth option. You could essentially have a hybrid between #2 and #3 exposed via a web portal or some such mechanism. So the protected code and this tool chain would live inside the IP provider's network and the interface would be: parameters go in, compiled library comes out.

Regarding my tracing/VPI questions, I think I wasn't clear. I was assuming that for this approach we wouldn't want tracing or VPI at all. You idea of encrypted traces is pretty cool though. That would be additionally advantageous over encrypted RTL. However, for the first pass, I would imagine we wouldn't have any access to the design besides what is necessary to drive it through the DPI. I think that's easiest to reason about and to sell to IP providers.

And a quick note on DPI compatibility: I did try to run the DPI library against Xsim. I found that I wasn't compiling the Verilator runtime into the library, but that was easily fixed. It's working now except it's not updating accum_q for some reason. I assume that's still some mistake I'm making with the build. That is all to say, this is still very much a work in progress.

    (1-5/5)