What the difference between CRC and checksum? - networking

What the difference between CRC and checksum?

CRC (Cyclic Redundancy Check) is a type of checksum, specifically a position dependent checksum algorithm (among others, such as Fletcher's checksum, Adler-32). As their name suggest, these detect positional changes as well, which makes them more robust - thus more widely used - than other checksum methods.

CRC refers to a specific checksum algorithm. Other types of checksums are XOR, modulus, and all the various cryptographic hashes.

Check out HowStuffWorks for a good description of both and how they differ.
From the page:
Cyclic Redundancy Check (CRC)
CRCs are similar in concept to checksums, but they use polynomial division to determine the value of the CRC
More info is given at the link above including an example of how a checksum is calculated.

Jeff Atwood (founder of Stack Overflow) wrote in his Checksums and Hashes blog post:
I learned to appreciate the value of the Cyclic Redundancy Check (CRC) algorithm in my 8-bit, 300 baud file transferring days. If the CRC of the local file matched the CRC stored in the file (or on the server), I had a valid download. I also learned a little bit about the pigeonhole principle when I downloaded a file with a matching CRC that was corrupt!
A checksum is an error-detection scheme that typically refers to a cryptographic hash function, though it also includes CRC. Here are three different types of checksum:
Cyclic Redundancy Checks like CRC32 are fast but collision-prone. They are not robust to collision attacks, meaning that somebody can take a given CRC and easily a second input that matches it.
Cryptographic hash functions like MD5 (weaker), SHA1 (weak), and SHA256 (strong) are specifically designed to be resistant to collision attacks. They are preferable to CRCs in every situation except speed; use the strongest algorithm you can computationally afford.
Key derivation functions like PBKDF2 and bcrypt are designed for passwords. They are checksums that are expensive to compute so that they're robust to brute-force attacks.
See also this Crypto.SE question on CRC vs SHA1. Wikipedia has a hash function security summary page that discusses collision-proneness of various cryptographic hashes.

Related

Decrypting MD5 hashed text when salt is known

Let's say I have the following MD5 hashed password:
bec0932119f0b0dd192c3bb5e5984eec
If I know that the original password was salted and hashed and know that instead of typical salt it was just wrapped in 'flag{}' before MD5 summing it.
How may I decrypt MD5 in this case?
The other answer is not correct in the definition of what you are trying. Let's begin with the formal definitions of Cryptographical hash functions' required resistances. The below from Cryptographic Hash-Function Basics: Definitions, Implications, and Separations for Preimage Resistance, Second-Preimage Resistance, and Collision Resistance by P. Rogaway and T. Shrimpton;
preimage-resistance — for essentially all pre-specified outputs, it is computationally infeasible to find any input which hashes to that output, i.e., to find any preimage x' such that h(x') = y when given any y for which a corresponding input is not known.
2nd-preimage resistance, weak-collision — it is computationally infeasible to find any second input which has the same output as any specified input, i.e., given x, to find a 2nd-preimage x' != x such that h(x) = h(x').
collision resistance, strong-collision — it is computationally infeasible to find any two distinct inputs x, x' which hash to the same output, i.e., such that h(x) = h(x').
Collisions and password cracking is not related. Actually, you are trying to find a pre-image that works with the given hash value and the salt. The cost of generic pre-image attacks is O(2^n) in the case of MD5 n=128 that is O(2^128). There is a pre-image attack on the MD5 that is better than the generic with a cost of 2^123.4
Finding Preimages in Full MD5 Faster Than Exhaustive Search
This attack still beyond the search of everybody (except the QC and that is another story). Even for the supercomputers or the collaborative power of the bitcoin miners.
As pointed above, MD5 is no longer cryptographically secure since its collision resistance is broken, even SHA-1 is no longer secure.
hashing is not encryption/decryption. That is really a long story here a short answer, Encryption is reversible but hashes are not ( consider the pigeonhole principle, and see one-way functions) [ minor note block cipher mode of operation like the CTR mode doesn't requires a PRP it can work with PRF and it is designed in this way]...
What can you do?
First, use the John the Ripper password cracker.
If not found, then
Build a fast pre-image attack on the MD5 up to some limit according to your budget. hashcat is a very powerful tool that you can benefit from it to build it. Here a hashcat performance;
hashcat with Nvidia RTX 3090 one can search for 65322.5 MH/s (Mega Hashes/ Seconds). That is 2^16 MH/s. The calculations - time, device cost, electricity costs - can be done according to target search space if known.
MD5 is a hash function, you cannot really decrypt the result (plz search difference between hash and decryption).
However - you may try to find a collision - an input giving the same hash. With some probability it will match the original input. Cryptographic hash functions are designed to be very difficult (unfeasible) to find a collision, however for the MD5 it is not valid anymore (that's why MD5 is considered as not safe to use)
You may check the resources Vlastimil Klima: Tunnels in Hash Functions: MD5 Collisions Within a Minute, there are some more references and tools linked related to the latest Tunnel attack.

Can there be collisions in file checksums?

I am creating a service that accepts a file as input and then performs some processing on that file. I would like to create a checksum of the file and then check a database to see if that file has already been processed and then pull the data from there rather than reprocessing it.
I have a few questions about this process.
1) Do I need to worry about checksum collisions? AKA - could two files ever return the same checksum?
2) I'm planning on using MD5 to calculate the hash - are there any faster ways to do this? Are there algorithms I should consider for other reasons?
1) Do I need to worry about checksum collisions?
I'm planning on using MD5 to calculate the has
There is a difference between a checksum (e. g. crc32) and cryptographic hash. Cryptographic hash is designed to be collision resistant.
It means using a hash may be the best option you have. The probability of collision is very low, maybe negligible, mathematically still higher than zero.
I'm planning on using MD5 to calculate the hash - are there any faster ways to do this? Are there algorithms I should consider for other reasons?
MD5 is fast, but not secure anymore. The hash has been broken and there are fast methods to produce multiple inputs resulting to the same hash output. Standard used today for hash is sha-256 (Until you are using md5 as checksum not concerning intentional collisions, you may be ok. Regardless that you should avoid crypto primitives which are considered obsolete)

How to encrypt text using CRC32

As far as i know CRC32 is an error-detecting code.
I did not use it before but i recieve some task to use CRC32 to encrypt some text.
Is it possible to use CRC32 to encrypt ?
As noted, a CRC is linear and easily reversible, which is precisely what you don't want for secure encryption.
However it is possible to encode data with a CRC, if there were some reason to do so. You can, for example, take four bytes of data, compute the CRC-32 of that data, and transmit the CRC-32 instead of the data. Repeat for the next four bytes. That CRC-32 can easily be inverted to get the original four bytes.
I have no idea why that might be useful, but it can be done.
i recieve some task to use CRC32 to encrypt some text.
As already commented, crc32 is checksum, not even cryptographic hash. That means it lacks important features to be used in cryptography
Lets assume (wrongly) you could use crc32 as a hash function.
In theory (long shot) you could build a stream cipher e. g. chain-hashing a key. You could encrypt data with it. Just I am pretty sure the solution would be not secure enough. (even now I am an amateur and I am quite confident I see several attack vectors on such a cipher, crc32 is simply too linear)

Identification of padding scheme in RSA

How to determine the padding scheme used in a RSA encrypted message?
The best way is probably to perform PKCS#1 v1.5 or OAEP decryption and see if you hit gold. The unpadding will fail if the wrong algorithm is chosen.
It is possible to raw decipher and then look at the resulting scheme by representing the padded message as hexadecimals. If the resulting octet string (byte array) starts with 0002 then it's likely PKCS#1 v1.5 padding. If it starts with 00 and then a random looking byte it's probably OAEP. As you can see, this is just a heuristic, not a full fledged algorithm. Note that OAEP's MFG1 can be parameterized with a hash function, but usually SHA-1 is used.
RSA-KEM is not used much, but as it results in a completely random key seed (possibly excluding the first bit), there is no way to test for RSA-KEM other than to expect RSA-KEM if the ciphertext and private key can be verified to be correct and the value doesn't match one of the other schemes / lacks structure.
The protocol should define which algorithm is used. Leaving the choice of algorithm to the decryption routine opens up your implementation to attacks. The security proof of ciphers doesn't allow for other algorithms to be chosen.
So you can use above to analyze the protocol, but please do not use it in your implementation to choose between algorithms in the field.

How to choose an AES encryption mode (CBC ECB CTR OCB CFB)?

Which of them are preferred in which circumstances?
I'd like to see the list of evaluation crtieria for the various modes, and maybe a discussion of the applicability of each criterion.
For example,
I think one of the criteria is "size of the code" for encryption and decryption, which is important for micro-code embedded systems, like 802.11 network adapters. IF the code required to implement CBC is much smaller than that required for CTR (I don't know this is true, it's just an example), then I could understand why the mode with the smaller code would be preferred. But if I am writing an app that runs on a server, and the AES library I am using implements both CBC and CTR anyway, then this criterion is irrelevant.
See what I mean by "list of evaluation criteria and applicability of each criterion" ??
This isn't really programming related but it is algorithm related.
Please consider long and hard if you can't get around implementing your own cryptography
The ugly truth of the matter is that if you are asking this question you will probably not be able to design and implement a secure system.
Let me illustrate my point: Imagine you are building a web application and you need to store some session data. You could assign each user a session ID and store the session data on the server in a hash map mapping session ID to session data. But then you have to deal with this pesky state on the server and if at some point you need more than one server things will get messy. So instead you have the idea to store the session data in a cookie on the client side. You will encrypt it of course so the user cannot read and manipulate the data. So what mode should you use? Coming here you read the top answer (sorry for singling you out myforwik). The first one covered - ECB - is not for you, you want to encrypt more than one block, the next one - CBC - sounds good and you don't need the parallelism of CTR, you don't need random access, so no XTS and patents are a PITA, so no OCB. Using your crypto library you realize that you need some padding because you can only encrypt multiples of the block size. You choose PKCS7 because it was defined in some serious cryptography standards. After reading somewhere that CBC is provably secure if used with a random IV and a secure block cipher, you rest at ease even though you are storing your sensitive data on the client side.
Years later after your service has indeed grown to significant size, an IT security specialist contacts you in a responsible disclosure. She's telling you that she can decrypt all your cookies using a padding oracle attack, because your code produces an error page if the padding is somehow broken.
This is not a hypothetical scenario: Microsoft had this exact flaw in ASP.NET until a few years ago.
The problem is there are a lot of pitfalls regarding cryptography and it is extremely easy to build a system that looks secure for the layman but is trivial to break for a knowledgeable attacker.
What to do if you need to encrypt data
For live connections use TLS (be sure to check the hostname of the certificate and the issuer chain). If you can't use TLS, look for the highest level API your system has to offer for your task and be sure you understand the guarantees it offers and more important what it does not guarantee. For the example above a framework like Play offers client side storage facilities, it does not invalidate the stored data after some time, though, and if you changed the client side state, an attacker can restore a previous state without you noticing.
If there is no high level abstraction available use a high level crypto library. A prominent example is NaCl and a portable implementation with many language bindings is Sodium. Using such a library you do not have to care about encryption modes etc. but you have to be even more careful about the usage details than with a higher level abstraction, like never using a nonce twice. For custom protocol building (say you want something like TLS, but not over TCP or UDP) there are frameworks like Noise and associated implementations that do most of the heavy lifting for you, but their flexibility also means there is a lot of room for error, if you don't understand in depth what all the components do.
If for some reason you cannot use a high level crypto library, for example because you need to interact with existing system in a specific way, there is no way around educating yourself thoroughly. I recommend reading Cryptography Engineering by Ferguson, Kohno and Schneier. Please don't fool yourself into believing you can build a secure system without the necessary background. Cryptography is extremely subtle and it's nigh impossible to test the security of a system.
Comparison of the modes
Encryption only:
Modes that require padding:
Like in the example, padding can generally be dangerous because it opens up the possibility of padding oracle attacks. The easiest defense is to authenticate every message before decryption. See below.
ECB encrypts each block of data independently and the same plaintext block will result in the same ciphertext block. Take a look at the ECB encrypted Tux image on the ECB Wikipedia page to see why this is a serious problem. I don't know of any use case where ECB would be acceptable.
CBC has an IV and thus needs randomness every time a message is encrypted, changing a part of the message requires re-encrypting everything after the change, transmission errors in one ciphertext block completely destroy the plaintext and change the decryption of the next block, decryption can be parallelized / encryption can't, the plaintext is malleable to a certain degree - this can be a problem.
Stream cipher modes: These modes generate a pseudo random stream of data that may or may not depend the plaintext. Similarly to stream ciphers generally, the generated pseudo random stream is XORed with the plaintext to generate the ciphertext. As you can use as many bits of the random stream as you like you don't need padding at all. Disadvantage of this simplicity is that the encryption is completely malleable, meaning that the decryption can be changed by an attacker in any way he likes as for a plaintext p1, a ciphertext c1 and a pseudo random stream r and attacker can choose a difference d such that the decryption of a ciphertext c2=c1⊕d is p2 = p1⊕d, as p2 = c2⊕r = (c1 ⊕ d) ⊕ r = d ⊕ (c1 ⊕ r). Also the same pseudo random stream must never be used twice as for two ciphertexts c1=p1⊕r and c2=p2⊕r, an attacker can compute the xor of the two plaintexts as c1⊕c2=p1⊕r⊕p2⊕r=p1⊕p2. That also means that changing the message requires complete reencryption, if the original message could have been obtained by an attacker. All of the following steam cipher modes only need the encryption operation of the block cipher, so depending on the cipher this might save some (silicon or machine code) space in extremely constricted environments.
CTR is simple, it creates a pseudo random stream that is independent of the plaintext, different pseudo random streams are obtained by counting up from different nonces/IVs which are multiplied by a maximum message length so that overlap is prevented, using nonces message encryption is possible without per message randomness, decryption and encryption are completed parallelizable, transmission errors only effect the wrong bits and nothing more
OFB also creates a pseudo random stream independent of the plaintext, different pseudo random streams are obtained by starting with a different nonce or random IV for every message, neither encryption nor decryption is parallelizable, as with CTR using nonces message encryption is possible without per message randomness, as with CTR transmission errors only effect the wrong bits and nothing more
CFB's pseudo random stream depends on the plaintext, a different nonce or random IV is needed for every message, like with CTR and OFB using nonces message encryption is possible without per message randomness, decryption is parallelizable / encryption is not, transmission errors completely destroy the following block, but only effect the wrong bits in the current block
Disk encryption modes: These modes are specialized to encrypt data below the file system abstraction. For efficiency reasons changing some data on the disc must only require the rewrite of at most one disc block (512 bytes or 4kib). They are out of scope of this answer as they have vastly different usage scenarios than the other. Don't use them for anything except block level disc encryption. Some members: XEX, XTS, LRW.
Authenticated encryption:
To prevent padding oracle attacks and changes to the ciphertext, one can compute a message authentication code (MAC) on the ciphertext and only decrypt it if it has not been tampered with. This is called encrypt-then-mac and should be preferred to any other order. Except for very few use cases authenticity is as important as confidentiality (the latter of which is the aim of encryption). Authenticated encryption schemes (with associated data (AEAD)) combine the two part process of encryption and authentication into one block cipher mode that also produces an authentication tag in the process. In most cases this results in speed improvement.
CCM is a simple combination of CTR mode and a CBC-MAC. Using two block cipher encryptions per block it is very slow.
OCB is faster but encumbered by patents. For free (as in freedom) or non-military software the patent holder has granted a free license, though.
GCM is a very fast but arguably complex combination of CTR mode and GHASH, a MAC over the Galois field with 2^128 elements. Its wide use in important network standards like TLS 1.2 is reflected by a special instruction Intel has introduced to speed up the calculation of GHASH.
Recommendation:
Considering the importance of authentication I would recommend the following two block cipher modes for most use cases (except for disk encryption purposes): If the data is authenticated by an asymmetric signature use CBC, otherwise use GCM.
ECB should not be used if encrypting more than one block of data with the same key.
CBC, OFB and CFB are similar, however OFB/CFB is better because you only need encryption and not decryption, which can save code space.
CTR is used if you want good parallelization (ie. speed), instead of CBC/OFB/CFB.
XTS mode is the most common if you are encoding a random accessible data (like a hard disk or RAM).
OCB is by far the best mode, as it allows encryption and authentication in a single pass. However there are patents on it in USA.
The only thing you really have to know is that ECB is not to be used unless you are only encrypting 1 block. XTS should be used if you are encrypting randomly accessed data and not a stream.
You should ALWAYS use unique IV's every time you encrypt, and they should be random. If you cannot guarantee they are random, use OCB as it only requires a nonce, not an IV, and there is a distinct difference. A nonce does not drop security if people can guess the next one, an IV can cause this problem.
A formal analysis has been done by Phil Rogaway in 2011, here. Section 1.6 gives a summary that I transcribe here, adding my own emphasis in bold (if you are impatient, then his recommendation is use CTR mode, but I suggest that you read my paragraphs about message integrity versus encryption below).
Note that most of these require the IV to be random, which means non-predictable and therefore should be generated with cryptographic security. However, some require only a "nonce", which does not demand that property but instead only requires that it is not re-used. Therefore designs that rely on a nonce are less error prone than designs that do not (and believe me, I have seen many cases where CBC is not implemented with proper IV selection). So you will see that I have added bold when Rogaway says something like "confidentiality is not achieved when the IV is a nonce", it means that if you choose your IV cryptographically secure (unpredictable), then no problem. But if you do not, then you are losing the good security properties. Never re-use an IV for any of these modes.
Also, it is important to understand the difference between message integrity and encryption. Encryption hides data, but an attacker might be able to modify the encrypted data, and the results can potentially be accepted by your software if you do not check message integrity. While the developer will say "but the modified data will come back as garbage after decryption", a good security engineer will find the probability that the garbage causes adverse behaviour in the software, and then he will turn that analysis into a real attack. I have seen many cases where encryption was used but message integrity was really needed more than the encryption. Understand what you need.
I should say that although GCM has both encryption and message integrity, it is a very fragile design: if you re-use an IV, you are screwed -- the attacker can recover your key. Other designs are less fragile, so I personally am afraid to recommend GCM based upon the amount of poor encryption code that I have seen in practice.
If you need both, message integrity and encryption, you can combine two algorithms: usually we see CBC with HMAC, but no reason to tie yourself to CBC. The important thing to know is encrypt first, then MAC the encrypted content, not the other way around. Also, the IV needs to be part of the MAC calculation.
I am not aware of IP issues.
Now to the good stuff from Professor Rogaway:
Block ciphers modes, encryption but not message integrity
ECB: A blockcipher, the mode enciphers messages that are a multiple of n bits by separately enciphering each n-bit piece. The security properties are weak, the method leaking equality of blocks across both block positions and time. Of considerable legacy value, and of value as a building block for other schemes, but the mode does not achieve any generally desirable security goal in its own right and must be used with considerable caution; ECB should not be regarded as a “general-purpose” confidentiality mode.
CBC: An IV-based encryption scheme, the mode is secure as a probabilistic encryption scheme, achieving indistinguishability from random bits, assuming a random IV. Confidentiality is not achieved if the IV is merely a nonce, nor if it is a nonce enciphered under the same key used by the scheme, as the standard incorrectly suggests to do. Ciphertexts are highly malleable. No chosen ciphertext attack (CCA) security. Confidentiality is forfeit in the presence of a correct-padding oracle for many padding methods. Encryption inefficient from being inherently serial. Widely used, the mode’s privacy-only security properties result in frequent misuse. Can be used as a building block for CBC-MAC algorithms. I can identify no important advantages over CTR mode.
CFB: An IV-based encryption scheme, the mode is secure as a probabilistic encryption scheme, achieving indistinguishability from random bits, assuming a random IV. Confidentiality is not achieved if the IV is predictable, nor if it is made by a nonce enciphered under the same key used by the scheme, as the standard incorrectly suggests to do. Ciphertexts are malleable. No CCA-security. Encryption inefficient from being inherently serial. Scheme depends on a parameter s, 1 ≤ s ≤ n, typically s = 1 or s = 8. Inefficient for needing one blockcipher call to process only s bits . The mode achieves an interesting “self-synchronization” property; insertion or deletion of any number of s-bit characters into the ciphertext only temporarily disrupts correct decryption.
OFB: An IV-based encryption scheme, the mode is secure as a probabilistic encryption scheme, achieving indistinguishability from random bits, assuming a random IV. Confidentiality is not achieved if the IV is a nonce, although a fixed sequence of IVs (eg, a counter) does work fine. Ciphertexts are highly malleable. No CCA security. Encryption and decryption inefficient from being inherently serial. Natively encrypts strings of any bit length (no padding needed). I can identify no important advantages over CTR mode.
CTR: An IV-based encryption scheme, the mode achieves indistinguishability from random bits assuming a nonce IV. As a secure nonce-based scheme, the mode can also be used as a probabilistic encryption scheme, with a random IV. Complete failure of privacy if a nonce gets reused on encryption or decryption. The parallelizability of the mode often makes it faster, in some settings much faster, than other confidentiality modes. An important building block for authenticated-encryption schemes. Overall, usually the best and most modern way to achieve privacy-only encryption.
XTS: An IV-based encryption scheme, the mode works by applying a tweakable blockcipher (secure as a strong-PRP) to each n-bit chunk. For messages with lengths not divisible by n, the last two blocks are treated specially. The only allowed use of the mode is for encrypting data on a block-structured storage device. The narrow width of the underlying PRP and the poor treatment of fractional final blocks are problems. More efficient but less desirable than a (wide-block) PRP-secure blockcipher would be.
MACs (message integrity but not encryption)
ALG1–6: A collection of MACs, all of them based on the CBC-MAC. Too many schemes. Some are provably secure as VIL PRFs, some as FIL PRFs, and some have no provable security. Some of the schemes admit damaging attacks. Some of the modes are dated. Key-separation is inadequately attended to for the modes that have it. Should not be adopted en masse, but selectively choosing the “best” schemes is possible. It would also be fine to adopt none of these modes, in favor of CMAC. Some of the ISO 9797-1 MACs are widely standardized and used, especially in banking. A revised version of the standard (ISO/IEC FDIS 9797-1:2010) will soon be released [93].
CMAC: A MAC based on the CBC-MAC, the mode is provably secure (up to the birthday bound) as a (VIL) PRF (assuming the underlying blockcipher is a good PRP). Essentially minimal overhead for a CBCMAC-based scheme. Inherently serial nature a problem in some application domains, and use with a 64-bit blockcipher would necessitate occasional re-keying. Cleaner than the ISO 9797-1 collection of MACs.
HMAC: A MAC based on a cryptographic hash function rather than a blockcipher (although most cryptographic hash functions are themselves based on blockciphers). Mechanism enjoys strong provable-security bounds, albeit not from preferred assumptions. Multiple closely-related variants in the literature complicate gaining an understanding of what is known. No damaging attacks have ever been suggested. Widely standardized and used.
GMAC: A nonce-based MAC that is a special case of GCM. Inherits many of the good and bad characteristics of GCM. But nonce-requirement is unnecessary for a MAC, and here it buys little benefit. Practical attacks if tags are truncated to ≤ 64 bits and extent of decryption is not monitored and curtailed. Complete failure on nonce-reuse. Use is implicit anyway if GCM is adopted. Not recommended for separate standardization.
authenticated encryption (both encryption and message integrity)
CCM: A nonce-based AEAD scheme that combines CTR mode encryption and the raw
CBC-MAC. Inherently serial, limiting speed in some contexts. Provably secure, with good bounds, assuming the underlying blockcipher is a good PRP. Ungainly construction that demonstrably does the job. Simpler to implement than GCM. Can be used as a nonce-based MAC. Widely standardized and used.
GCM: A nonce-based AEAD scheme that combines CTR mode encryption and a GF(2128)-based universal hash function. Good efficiency characteristics for some implementation environments. Good provably-secure results assuming minimal tag truncation. Attacks and poor provable-security bounds in the presence of substantial tag truncation. Can be used as a nonce-based MAC, which is then called GMAC. Questionable choice to allow nonces other than 96-bits. Recommend restricting nonces to 96-bits and tags to at least 96 bits. Widely standardized and used.
Anything but ECB.
If using CTR, it is imperative that you use a different IV for each message, otherwise you end up with the attacker being able to take two ciphertexts and deriving a combined unencrypted plaintext. The reason is that CTR mode essentially turns a block cipher into a stream cipher, and the first rule of stream ciphers is to never use the same Key+IV twice.
There really isn't much difference in how difficult the modes are to implement. Some modes only require the block cipher to operate in the encrypting direction. However, most block ciphers, including AES, don't take much more code to implement decryption.
For all cipher modes, it is important to use different IVs for each message if your messages could be identical in the first several bytes, and you don't want an attacker knowing this.
Have you start by reading the information on this on Wikipedia - Block cipher modes of operation? Then follow the reference link on Wikipedia to NIST: Recommendation for Block Cipher Modes of Operation.
You might want to chose based on what is widely available. I had the same question and here are the results of my limited research.
Hardware limitations
STM32L (low energy ARM cores) from ST Micro support ECB, CBC,CTR GCM
CC2541 (Bluetooth Low Energy) from TI supports ECB, CBC, CFB, OFB, CTR, and CBC-MAC
Open source limitations
Original rijndael-api source - ECB, CBC, CFB1
OpenSSL - command line CBC, CFB, CFB1, CFB8, ECB, OFB
OpenSSL - C/C++ API CBC, CFB, CFB1, CFB8, ECB, OFB and CTR
EFAES lib [1] - ECB, CBC, PCBC, OFB, CFB, CRT ([sic] CTR mispelled)
OpenAES [2] - ECB, CBC
[1] http://www.codeproject.com/Articles/57478/A-Fast-and-Easy-to-Use-AES-Library
[2] https://openaes.googlecode.com/files/OpenAES-0.8.0.zip
There are new timing vulnerabilities in the CBC mode of operation.
https://learn.microsoft.com/en-us/dotnet/standard/security/vulnerabilities-cbc-mode
Generally the sole existence of a chaining mode already reduces the theoretically security as chaining widens the attack surface and also make certain kind of attacks more feasible. On the other hand, without chaining, you can at most encrypt 16 bytes (128 bits) securely, as that's the block size of AES (also of AES-192 and AES-256) and if your input data exceeds that block size, what else would you do than using chaining? Just encrypting the data block by block? That would be ECB and ECB has the worst security to begin with. Anything is more secure than ECB.
Most security analyses recommend that you always use either CBC or CTR, unless you can name any reason why you cannot use one of these two modes. And out of these two modes, they recommend CBC if security is your main concern and CTR if speed is your main concern. That's because CTR is slightly less secure than CBC because it has a higher likeliness of IV (initialization vector) collision, since the presence of the CTR counter reduces the IV value space, and attackers can change some ciphertext bits to damage exactly the same bits in plaintext (which can be an issue if the attacker knows exact bit positions in the data). On the other hand, CTR can be fully parallelized (encryption and decryption) and requires no data padding to a multiple of the block size.
That said, they still claim CFB and OFB to be secure, however slightly less secure and they have no real advantages to begin with. CFB shares the same weaknesses as CBC and on top of that isn't protected against replay attacks. OFB shares the same weaknesses as CTR but cannot be parallelized at all. So CFB is like CBC without padding but less secure and OFB is like CTR but without its speed benefits and a wider attack surface.
There is only one special case where you may want to use OFB and that's if you need to decrypt data in realtime (e.g. a stream of incoming data) on hardware that is actually too weak for doing so, yet you will know the decryption key way ahead of time. As in that case, you can pre-calculate all the XOR blocks in advance and store them somewhere and when the real data arrives, the entire decryption is just XOR'ing the incoming data with the stored XOR blocks and that requires very little computational power. That's the one thing you can do with OFB that you cannot do with any other chaining.
For performance analysis, see this paper.
For a detailed evaluation, including security, see this paper.
I know one aspect: Although CBC gives better security by changing the IV for each block, it's not applicable to randomly accessed encrypted content (like an encrypted hard disk).
So, use CBC (and the other sequential modes) for sequential streams and ECB for random access.

Resources